神奇时刻:2006-01-02 15:04:05
1 官方文档
time package(需科学上网查看):https://golang.org/pkg/time/
2 自定义时间格式
在看代码之前,先问一个关键问题:你懂 2006-01-02 15:04:05 么?不懂还是看代码吧!
package main
import (
"fmt"
"time"
)
func main() {
// 使用系统默认格式打印当前时间
t1 := time.Now();
fmt.Println("t1:", t1)
// 自定义格式,相当于Java中的时间格式:yyyy-MM-dd HH:mm:ss
t2 := t1.Format("2006-01-02 15:04:05")
fmt.Println("t2:", t2)
// 换个时间定义格式不行么?答案:不行
t3 := t1.Format("2018-10-01 15:18:00")
fmt.Println("t3:", t3)
// 自定义解析时间字符串格式
t4, _ := time.Parse("2006-01-02 15:04:05", "2018-10-01 14:51:00")
fmt.Println("t4:", t4)
}
示例输出:
t1: 2018-10-01 15:35:54.7057525 +0800 CST m=+0.006020701
t2: 2018-10-01 15:35:54
t3: 1108-100-10 15:108:00
t4: 2018-10-01 14:51:00 +0000 UTC
简而言之,其他常规语言使用字母 “ymd” 编写时间格式,而 golang 使用固定的时刻 "2006-01-02 15:04:05" 编写时间格式。 优点就是所见即所得,立刻看到效果,缺点就是,你要记住这个时刻,这是目前为止遇到的第一个挑战。至于为什么是这个时时刻?它有什么意义?我不知道。
标准库内置定义的时间格式常量如下:
const (
ANSIC = "Mon Jan _2 15:04:05 2006"
UnixDate = "Mon Jan _2 15:04:05 MST 2006"
RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
RFC822 = "02 Jan 06 15:04 MST"
RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
RFC3339 = "2006-01-02T15:04:05Z07:00"
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
Kitchen = "3:04PM"
// Handy time stamps.
Stamp = "Jan _2 15:04:05"
StampMilli = "Jan _2 15:04:05.000"
StampMicro = "Jan _2 15:04:05.000000"
StampNano = "Jan _2 15:04:05.000000000"
)
看了之后,叹了口气,为啥常用的 "2006-01-02 15:04:05" 时间格式都没有,看来以后还得自食其力。
3 时区
由于世界各国家与地区经度不同,地方时也有所不同,因此会划分为不同的时区。正式的时区划分,其中包括24个时区,每一时区由一个英文字母表示。每隔经度15°划分一个时区。
3.1 如何计算区时?
计算的区时=已知区时-(已知区时的时区-要计算区时的时区),(注:东时区为正,西时区为负)。
下面举例加以说明:
例1:已知东京(东九区)时间为5月1日12:00,求北京(东八区)的区时?
北京时间=12:00-(9-8)=11:00(即北京时间为5月1日11:00)。
3.2 UTC
UTC 不属于任意时区 。协调世界时,又称世界统一时间,世界标准时间,国际协调时间,简称 UTC。
3.3 时区解析
下面是几个解析时区的例子,这个问题困了我一周。代码如下:
// 考虑时区:下面对么?答案:不对
t5, _ := time.Parse("2006-01-02T15:04:05Z07:00", "2018-10-01T16:27:00Z08:00")
fmt.Println("t5:", t5) // 输出:t5: 0001-01-01 00:00:00 +0000 UTC
// 考虑时区:上面正确的格式是把 "Z" 替换成 "+" 或者 "-",分别代表正负时区。
t6, _ := time.Parse("2006-01-02T15:04:05Z07:00", "2018-10-01T16:27:00+08:00")
fmt.Println("t6:", t6) // 输出:t6: 2018-10-01 16:27:00 +0800 CST
// 考虑时区:如果解析的格式不带时区,将由 time.ParseInLocation 第三个参数决定
t7, _ := time.ParseInLocation("2006-01-02T15:04:05", "2018-10-01T16:27:00", time.Local)
fmt.Println("t7:", t7) // 输出:t7: 2018-10-01 16:27:00 +0800 CST
// 考虑时区:使用 UTC
t8, _ := time.ParseInLocation("2006-01-02T15:04:05", "2018-10-01T16:27:00", time.UTC)
fmt.Println("t8:", t8) // 输出:t8: 2018-10-01 16:27:00 +0000 UTC
官方例子代码如下:
// See the example for Time.Format for a thorough description of how
// to define the layout string to parse a time.Time value; Parse and
// Format use the same model to describe their input and output.
// longForm shows by example how the reference time would be represented in
// the desired layout.
const longForm = "Jan 2, 2006 at 3:04pm (MST)"
t, _ := time.Parse(longForm, "Feb 3, 2013 at 7:54pm (PST)")
fmt.Println(t)
// shortForm is another way the reference time would be represented
// in the desired layout; it has no time zone present.
// Note: without explicit zone, returns time in UTC.
const shortForm = "2006-Jan-02"
t, _ = time.Parse(shortForm, "2013-Feb-03")
fmt.Println(t)
// Some valid layouts are invalid time values, due to format specifiers
// such as _ for space padding and Z for zone information.
// For example the RFC3339 layout 2006-01-02T15:04:05Z07:00
// contains both Z and a time zone offset in order to handle both valid options:
// 2006-01-02T15:04:05Z
// 2006-01-02T15:04:05+07:00
t, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
fmt.Println(t)
t, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05+07:00")
fmt.Println(t)
_, err := time.Parse(time.RFC3339, time.RFC3339)
fmt.Println("error", err) // Returns an error as the layout is not a valid time value
输出如下:
2013-02-03 19:54:00 -0800 PST
2013-02-03 00:00:00 +0000 UTC
2006-01-02 15:04:05 +0000 UTC
2006-01-02 15:04:05 +0700 +0700
error parsing time "2006-01-02T15:04:05Z07:00": extra text: 07:00
官方解释很清楚,对于 time.RFC3339 (2006-01-02T15:04:05Z07:00) 中的 Z , 包含单独的 "Z" 或者是包含正负号的时区偏移都是有效格式,例如:
- 2006-01-02T15:04:05Z
- 2006-01-02T15:04:05+07:00
更多关于 time.Parse 函数的详情可参考:官方文档 time.Parse 说明
有疑问加站长微信联系(非本文作者)