小编典典

在Golang中全局设置时区

go

我正在尝试为我的应用程序修改golang时区

我看了一下 时间 包,初始化时区发生在

time / zoneinfo_unix.go @ initLocal

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

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


到目前为止我尝试过的

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

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

2-没有工作

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

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


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

Docker镜像:golang:1.11.2


阅读 1465

收藏
2020-07-02

共1个答案

小编典典

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

如何保证?创建一个除了设置时区外什么都不做的包(以后您可以添加其他东西,但是对于我们的示例来说就足够了)。

像这样:

package tzinit

import (
    "os"
)

func init() {
    os.Setenv("TZ", "Africa/Cairo")
}

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

package main

import _ "path/to/tzinit"

// Your other, "regular" imports:
import (
    "fmt"
    "os"
    "time"
    ...
)

因此,设置TZenv var会在其他任何软件包无法访问该time软件包之前进行。

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

一句话警告。


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

为了确保可重现的初始化行为,鼓励构建系统以词法文件名的顺序向编译器提供属于同一软件包的多个文件。

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

2020-07-02