我正在try 为我的应用程序修改Golang时区

我已经看过time包了,初始化时区发生在

时间/区域信息.转到@initLocal

该函数简单地try 读取环境变量TZ,如果它是有效的,则加载它

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


到目前为止我都试过了

1-效果很好-但我不想使用这两种方法中的任何一种:

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

2-不起作用

  • 在我的应用程序初始化中(应用程序初始化在主应用程序中导入的一个单独的包中),我使用操作系统.SetEnv("TZ","非洲/ cairo ")

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


关于如何使第二种方法起作用,有什么 idea 吗?

docker 镜像:Golang:1.11.2

推荐答案

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

如何确保这一点?创建一个除了设置时区之外什么也不做的包(稍后您可以向其添加其他内容,但对于我们的示例来说就足够了).

如下所示:

package tzinit

import (
    "os"
)

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

将这tzinit个包first导入您的main包中,如下所示:

package main

import _ "path/to/tzinit"

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

因此,设置TZenv变量将在任何其他包可以访问time包之前进行.

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

A word of warning.

Spec: Package initialization规定了初始化包的要求和规则,并且没有指定处理导入的顺序(唯一能保证的是所有引用的包在可以使用之前都将被递归初始化).这意味着,尽管当前的编译器按照列出的方式处理它们,但您不能百分之百依赖这一点.即使对于main软件包,也存在拥有多个源文件的问题,将它们以不同的顺序提供给编译器也可能会改变初始化顺序.该规范将此作为"推荐":

为了确保可复制的初始化行为,建议构建系统以词法文件名顺序向编译器呈现属于同一个包的多个文件.

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

Go相关问答推荐

Golang Cososdb-gremlin连接

如何将GoFr筛选器用于查询参数?

CURL和Postman HTTP POST工作,但Golang请求失败,状态为400

Date.Format正在输出非常奇怪的日期

如何修复proxyconnect tcp:tls:第一条记录看起来不像tls握手

Golang Gorm Fiber - 如何将定义为别名的名称发送到索引模板?

testcontainers:如何修复绑定源路径不存在

Go Build删除信息

Golang 发送Post请求出现400错误

以编程方式取消 pyspark dataproc 批处理作业(job)

Neptune 在连接到启用 IAM 的 Neptune 实例时抛出握手错误错误

为什么不同的 Wireguard 私钥会产生相同的公钥?

如何为导入的嵌入式 struct 文字提供值?

Golang 工作池实现意外工作

如何通过组合来自不同包的接口来创建接口?

如何使用golang操作很长的字符串以避免内存不足

Golang 泛型

使用 LoadLibraryA(path_to_dll) 加载 DLL 会将文件描述符 0、1 和 2 的继承句柄标志 (HANDLE_FLAG_INHERIT) 从 1 更改为 0

Scanner.Buffer - 最大值对自定义拆分没有影响?

Go 1.18 泛型如何使用接口定义新的类型参数