为什么 time.Parse
不使用时区信息?它应该针对不同的时区返回不同的时间。
代码
package main
import (
"fmt"
"time"
)
func main() {
t, err := time.Parse("2006-01-02 MST", "2018-05-11 IST")
if err != nil {
return
}
t2, err := time.Parse("2006-01-02 MST", "2018-05-11 UTC")
if err != nil {
return
}
fmt.Println(t.Unix())
fmt.Println(t2.Unix())
}
输出:
1525996800
1525996800
最佳答案
对问题本身的一些解释:
这 2 个时间戳 2018-05-11 IST
和 2018-05-11 UTC
不指定同一时刻,因为 IST 与 UTC 具有不同的偏移量:印度标准时间 (IST) 比协调世界时 (UTC) 早 5:30。
和Time.Unix()
返回自引用时间(UTC 时间 1970 年 1 月 1 日)以来经过的秒数。这意味着输出应该不同!
在 PlayGround 上运行你的代码确实给出了错误的结果(link)。
这是一个与时区相关的问题。如果您尝试加载 IST 时区:
loc, err := time.LoadLocation("IST")
fmt.Println(loc, err)
输出:
UTC cannot find IST in zip file /usr/local/go/lib/time/zoneinfo.zip
而“IST”不被支持的原因是因为它有歧义。它可能表示印度、爱尔兰、以色列等时区,它们具有不同的时区偏移量和规则。
和 time.Parse()
的文档指出
If the zone abbreviation is unknown, Parse records the time as being in a fabricated location with the given zone abbreviation and a zero offset.
因此 parse.Parse()
返回的 time.time
将像 UTC 时区一样具有 0 偏移量,因此它会产生相同的“unix 时间” (Time.Unix()
将返回相同的值)。
但是在本地(使用我的 CET)时区运行它会给出不同的正确结果:
t, err := time.Parse("2006-01-02 MST", "2018-05-11 CET")
if err != nil {
panic(err)
}
t2, err := time.Parse("2006-01-02 MST", "2018-05-11 UTC")
if err != nil {
panic(err)
}
fmt.Println(t)
fmt.Println(t2)
fmt.Println(t.Unix())
fmt.Println(t2.Unix())
输出:
2018-05-11 01:00:00 +0200 CEST
2018-05-11 00:00:00 +0000 UTC
1525993200
1525996800
time.Parse()
的文档关于用时区缩写解析时间有这样的说法:
When parsing a time with a zone abbreviation like MST, if the zone abbreviation has a defined offset in the current location, then that offset is used. The zone abbreviation "UTC" is recognized as UTC regardless of location. If the zone abbreviation is unknown, Parse records the time as being in a fabricated location with the given zone abbreviation and a zero offset. This choice means that such a time can be parsed and reformatted with the same layout losslessly, but the exact instant used in the representation will differ by the actual zone offset. To avoid such problems, prefer time layouts that use a numeric zone offset, or use ParseInLocation.
文档建议使用带有数字区域偏移量的布局进行解析,如下所示:
t, err := time.Parse("2006-01-02 -0700", "2018-05-11 +0530")
if err != nil {
panic(err)
}
然后输出(在 Go Playground 上试试):
2018-05-11 00:00:00 +0530 +0530
2018-05-11 00:00:00 +0000 UTC
1525977000
1525996800
另一种选择是使用 time.FixedZone()
自己构造 IST
,并使用 time.ParseInLocation()
,传递我们的手册 IST
位置:
ist := time.FixedZone("IST", 330*60) // +5:30
t, err := time.ParseInLocation("2006-01-02 MST", "2018-05-11 IST", ist)
输出将是(在 Go Playground 上尝试):
2018-05-11 00:00:00 +0530 IST
2018-05-11 00:00:00 +0000 UTC
1525977000
1525996800
另一种选择是通过加尔各答市加载印度 IST 区域:
loc, err := time.LoadLocation("Asia/Kolkata")
if err != nil {
panic(err)
}
这将产生相同的输出。在 Go Playground 上试用.
关于parsing - 为什么 time.Parse 不使用时区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50287664/