我正在尝试为我的应用程序

修改golang时区

我看过时间包,初始化时区发生在

time/zoneinfo_unix.go @ initLocal

该函数只是尝试读取环境变量TZ,如果有效,它将加载它

,如果不是,则回退/etc/localtime,如果无效,则回退到UTC

到目前为止我已经尝试过的

1-工作正常-但我不想使用这些方法中的任何一种-:

  • 在我的docker文件中,我将ENV传递给了容器TZ = Africa/Cairo
  • 进入容器bash,运行$ export TZ = Africa/Cairo

2-没工作

  • 在我的应用程序初始化中(应用程序初始化在一个单独的软件包中,该软件包正在主要导入中),我使用os.SetEnv(" TZ"," Africa / Cairo")

当我简化主体并使用os.SetEnv(" TZ"," Africa / Cairo")而不导入除" os-time"以外的任何其他软件包时,它可以按预期工作

关于如何使第二种方法起作用的任何想法吗?

Docker镜像:golang:1.11.2


您可以使用os.Setenv("TZ","Africa/Cairo")从应用程序内部实现所需的功能,重要的是必须在其他任何程序包使用time程序包中的任何内容之前调用此函数。

如何确保?创建一个除了设置时区外不执行其他任何操作的程序包(以后您可以在其中添加其他内容,但是对于我们的示例来说就足够了)。

赞:

首先将此tzinit包导入您的main包中,如下所示:

因此设置TZ env var将会在其他任何软件包都可以访问time软件包之前进行。

请注意,我只是为tzinit使用了单独的import声明,其原因是因为许多代码编辑器/ IDE会按字母顺序重新排列导入,这将确保导入tzinit仍是第一个导入。

警告语。

"规范:程序包初始化"说明了程序包初始化的要求和规则,并且未指定导入的处理顺序(唯一可以保证的是,所有引用的程序包将在使用前递归地初始化)。这意味着,尽管当前的编译器按列出的方式处理它们,但您不能100%依靠它。即使对于main包,也存在多个源文件的问题,以不同的顺序提供给编译器也可能会更改初始化顺序。规范将其作为"建议":

To ensure reproducible initialization behavior, build systems are encouraged to present multiple files belonging to the same package in lexical file name order to a compiler.

为了安全起见,最好是在启动Go应用程序之前设置TZ环境变量。


在这里为偶然浏览此页面的人添加我的分析服务。
time包中有一个全局变量,在main.go

中像这样使用它

您的系统必须安装了时区数据库。
在docker中,您必须apt get / apk add tzdata。但是,如果您使用的是go1.15,则还可以嵌入时区数据库,而无需在系统上安装tzdata


我可能迟到了,但是在全局环境中设置时区并不是一种可靠的方法。
应该在变量或结构中全局设置。以下是在变量中设置的时区的示例。同样在Go Playground