将Go的UnixDate时间转换为RFC3339格式无法保留时区

huangapple go评论75阅读模式
英文:

Converting a Go Time from UnixDate to RFC3339 Fails to Preserve TimeZone

问题

我正在使用Go的time包将一个以UnixDate格式化的时间字符串转换为RFC3339格式化的时间。这在我的本地机器上似乎很容易并且运行良好,但是在远程主机上运行时,时区信息似乎丢失了。

输入的时间是澳大利亚东部标准时间(EST),但似乎被time.Parse()解释为UTC。

代码片段在这里可用:

package main

import "fmt"
import "time"

func main() {
    t,_ := time.Parse(time.UnixDate,"Mon Jan 14 21:50:45 EST 2013")
    fmt.Println(t.Format(time.RFC3339))  // 打印时间为Z
    
    t2,_:=time.Parse(time.RFC3339,t.Format(time.RFC3339))
    fmt.Println(t2.Format(time.UnixDate)) // 打印时间为UTC
}

我需要特别设置区域设置或其他什么吗?

英文:

I am converting a UnixDate formatted time string to an RFC3339 formatted time using Go's time package. This seems to be easy and works well on my local machine, but when run on a remote host, the timezone info seems to get lost.

The input time is Eastern Australian Standard Time (EST) and seems to be interpreted as UTC by time.Parse().

Code snippet available here:

package main

import "fmt"
import "time"

func main() {
	t,_ := time.Parse(time.UnixDate,"Mon Jan 14 21:50:45 EST 2013")
	fmt.Println(t.Format(time.RFC3339))  // prints time as Z
	
	t2,_:=time.Parse(time.RFC3339,t.Format(time.RFC3339))
	fmt.Println(t2.Format(time.UnixDate)) // prints time as UTC
}

Do I need to specifically set locales or anything?

答案1

得分: 3

时区解析在Go中并不总是按预期工作。但这在很大程度上是因为时区缩写名称是模糊的。例如,在您的情况下,EST是指东澳大利亚标准时间(GMT+11)还是东部标准时间(GMT-5)?

如果您的本地时间是“东澳大利亚标准时间”,Go将假设您指的是本地时间。这就是为什么它在您的本地计算机上工作的原因。但由于服务器不使用它作为本地时间,所以没有理由假设您指的是悉尼时间。相反,Go选择了EST时区中的任何一个,并创建了一个名为“EST”的虚拟time.Location,但其效果是UTC。唯一能够告诉它最初意味着EST的方法是调用t.Location().String()

time包的作者写了一个关于时区解析工作原理的错误报告,在这里

英文:

Timezone parsing in Go doesn't always work as expected. But that is a great deal due to the fact that timezone abbreviation names are ambiguous. For example, does EST in your scenario mean Eastern Australian Standard Time (GMT+11) or Eastern Standard Time (GMT-5)?

If your local time is "Eastern Australian Standard Time", Go will assume you mean local time. That is why it worked on your local computer. But since the server is not using that as local time, there is no reason to assume you mean Sydney time. Instead, Go chooses neither of the EST timezones and creates a fake time.Location with the name "EST" but the effect of UTC. The only way to tell it was originally meant to be EST would be to call t.Location().String().

The author of the time package wrote a bug report explaining how the timezone parsing works here.

huangapple
  • 本文由 发表于 2013年1月14日 20:10:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/14318193.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定