时区在 Go 1.13 中加载失败

  • 本文关键字:加载 失败 Go 时区 go
  • 更新时间 :
  • 英文 :


这个简单的代码:

tzloc, err := time.LoadLocation(service.Settings.TimezoneName)
if err != nil {
panic(err)
}

在 Go 1.12 中运行良好,但在 1.13 中,它因"未知时区澳大利亚/墨尔本"而失败。我敢肯定它在某些环境中有效,但无论出于何种原因,它在 1.13 中对我们来说是被破坏的。通过恢复到 1.12 立即修复。我想知道是否有人知道 1.13 中的任何问题或原因,为什么尽管发行说明有这样的保证,但这会失败:"与往常一样,该版本保持了 Go 1 的兼容性承诺。我们希望几乎所有的 Go 程序都能像以前一样继续编译和运行。

对于 docker,通过添加 tzdata 或等效包来解决。这解决了使用 go 1.13 时的问题

http://pouzek.si/blog/go-loadlocation-docker/

FROM gliderlabs/alpine:3.3
RUN apk add --no-cache tzdata
COPY out/go-loadlocation-docker /go-loadlocation-docker
ENTRYPOINT ["/go-loadlocation-docker"]

这发生在我们身上,我们将zoneinfo.zip文件与我们的程序捆绑在一起,因为我们需要在Windows服务器上运行它。我们将 ZONEINFO 环境变量设置为包含.zip文件的路径,然后调用time.LoadLocation("America/Chicago")。在 1.12 版中,这很好。我们升级到版本 1.13,并在调用 LoadLocation 时遇到"系统找不到指定的路径"的问题。

在我们的例子中,将捆绑的zoneinfo.zip文件从 golang 存储库更新到最新版本解决了这个问题。我们之前使用的版本来自提交af3c48096。不确定这是否与您遇到的问题相同,因为目前还不清楚您是否像我们一样部署了该zip文件,但我想我会为遇到该问题的其他任何人插话。

注意:这只影响未安装 Go 版本 1.13 的情况 - 当我在本地运行它时,一切都很好,因为它回退到 $GOROOT 文件夹中的版本(从安装 1.13 时更新(。错误发生在没有安装 Go 的 Windows 机器上,如果我删除了 $GOROOT\lib\time\zoneinfo.zip 文件,也会在本地发生错误。

如果你正好Australia/Melbourne传递给time.LoadLocation,那么你应该检查 zoneinfo 文件。

https://golang.org/pkg/time/#LoadLocation

该名称被视为与 IANA 时区数据库中的文件相对应的位置名称。

LoadLocation 所需的时区数据库可能并非存在于所有系统上,尤其是非 Unix 系统上。LoadLocation 查找由 ZONEINFO 环境变量命名的目录或未压缩的 zip 文件(如果有(,然后在 Unix 系统上查找已知的安装位置,最后查找 $GOROOT/lib/time/zoneinfo.zip。

导入 time/tzdata 将导致时区信息嵌入到程序中。因此,如果时间包在系统上找不到 tzdata 文件,它将使用此嵌入的信息。

请记住,根据文档:

导入此包将使程序的大小增加约 450 KB。

示例代码可以是这样的:

package main
import (
"fmt"
"time"
_ "time/tzdata"
)
func main() {
loc, err := time.LoadLocation("Australia/Melbourne")
if err != nil {
panic(err)
}
fmt.Println(loc)
}

使用time.LoadLocation中的硬编码时区字符串进行测试。我怀疑您的TimezoneName变量中可能有空格。

否则,加载位置在 Go1.13 中按预期工作正常。

package main
import (
"fmt"
"time"
)
func main() {
location, err := time.LoadLocation("Australia/Melbourne")
if err != nil {
panic(err)
}
timeInUTC := time.Date(2018, 8, 30, 12, 0, 0, 0, time.UTC)
fmt.Println(timeInUTC.In(location))
}

上面的代码在 Go Playground 中将2018-08-30 22:00:00 +1000 AEST作为输出。Go Playground 使用 go 1.13。

但是如果我在周围放一个空间

location, err := time.LoadLocation("Australia/Melbourne ")
if err != nil {
panic(err)
}

它给出了您遇到的错误。

恐慌:时区未知 澳大利亚/墨尔本

最新更新