为什么Go时间.格式返回不同的值基于时区?



我以为时间到了。格式应该根据版式对时间进行格式化。但似乎它会根据时区信息返回不同的值。

package main
import (
"fmt"
"time"
)
func main() {
formats := []string{
time.RFC3339,
}
times := []string{
"2020-03-08T01:59:50-08:00",
"2020-03-08T01:59:59-08:00", //daylight saving starts 1 second later
"2020-03-08T05:59:59-08:00",
}
for _, f := range formats {
for _, t := range times {
fmt.Printf("Format: %sn", f)
t, err := time.Parse(f, t)
if err != nil {
panic(err)
}
fmt.Printf("unix: %dn", t.UnixNano())
fmt.Printf("time: %sn", t.Format(f))
t = t.Add(time.Second)
fmt.Printf("time + 1s: %sn", t.Format(f))
}
}
}

运行输出:

➜ go version
go version go1.15 darwin/amd64
➜ TZ=UTC go run main.go
Format: 2006-01-02T15:04:05Z07:00
unix: 1583661590000000000
time: 2020-03-08T01:59:50-08:00
time + 1s: 2020-03-08T01:59:51-08:00
Format: 2006-01-02T15:04:05Z07:00
unix: 1583661599000000000
time: 2020-03-08T01:59:59-08:00
time + 1s: 2020-03-08T02:00:00-08:00 (a: this is not expected)
unix: 1583675999000000000
time: 2020-03-08T05:59:59-08:00
time + 1s: 2020-03-08T06:00:00-08:00
➜ TZ=America/Los_Angeles go run main.go
Format: 2006-01-02T15:04:05Z07:00
unix: 1583661590000000000
time: 2020-03-08T01:59:50-08:00
time + 1s: 2020-03-08T01:59:51-08:00
Format: 2006-01-02T15:04:05Z07:00 
unix: 1583661599000000000
time: 2020-03-08T01:59:59-08:00
time + 1s: 2020-03-08T03:00:00-07:00 (b: this is expected)
Format: 2006-01-02T15:04:05Z07:00
unix: 1583675999000000000
time: 2020-03-08T05:59:59-08:00
time + 1s: 2020-03-08T06:00:00-08:00 (c: this contradicts with the b)

记录了该行为。time.Format的输出只是一个结果,而不是混淆的来源-time.Parse:

函数解析:

在解析具有-0700这样的区域偏移量的时间时,如果对应于当前位置(Local)使用的时区,则Parse在返回的时间中使用该位置和区域。否则它将时间记录为在一个固定的时间位置上给定的区域偏移量。

进一步的解释见<<strong>类型位置/strong>:

Local表示系统的本地时区。在Unix系统上,是Local查询TZ环境变量以查找要使用的时区。没有TZ表示使用系统默认的/etc/local时间TZ =";"表示使用UTC。TZ ="foo"表示在系统时区目录下使用文件foo。

基本上,go的解析器试图从UTC偏移量推断时区。如果解析的UTC偏移量与TZ环境变量设置的时区匹配,则在返回的time中设置该时区。当涉及到处理日期时,简单似乎总是结束了。时间。

最新更新