在Golang中全局设置时区 [英] Setting timezone globally in golang

查看:1014
本文介绍了在Golang中全局设置时区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to modify golang timezone for my application

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

I have took a look at time package, initializing timezone happens in

time/zoneinfo_unix.go @ initLocal

time/zoneinfo_unix.go @ initLocal

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

The function simply tries to read environment variable TZ and if it's valid it loads it

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

and if it's not it falls back /etc/localtime and if it's not valid it falls back to UTC

到目前为止我尝试过的

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

1- works fine -But i don't want to use either of those approaches - :

  • 在我的docker文件中,我将ENV传递给了容器TZ = Africa/Cairo
  • 进入容器bash,运行$ export TZ = Africa/Cairo
  • in my docker file i pass an ENV to the container, TZ = Africa/Cairo
  • getting into the container bash, running $ export TZ = Africa/Cairo

2-没用

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

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

When i simplify the main and use os.SetEnv("TZ", "Africa/Cairo") without importing any other packages other than "os - time" it works as expected

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

Any ideas about how to make the second approache work ?

Docker映像:golang:1.11.2

Docker image: golang:1.11.2

推荐答案

您可以使用os.Setenv("TZ", "Africa/Cairo")从应用程序内部实现所需的功能,重要的是必须在其他程序包使用包装.

You can achieve what you want from inside your app using os.Setenv("TZ", "Africa/Cairo"), what matters is that you must call this before any other package uses anything from the time package.

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

How to ensure that? Create a package that does nothing else except sets the timezone (later you may add other things to it, but for our example that's enough).

赞:

package tzinit

import (
    "os"
)

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

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

Import this tzinit package first thing in your main package like this:

package main

import _ "path/to/tzinit"

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

因此设置TZ env var将会在其他程序包访问time程序包之前发生.

And so setting the TZ env var will happen before any other package could access the time package.

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

Note that I used a separate import declaration just for tzinit, and the reason for this is because many code editors / IDEs will rearrange your imports alphabetically, this will ensure that importing tzinit will remain the first import.

警告语.

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

The Spec: Package initialization states the requirements and rules of initializing packages, and the order in which imports are processed is not specified (only thing guaranteed is that all referenced package will be initialized recursively before it can be used). This means that although current compilers process them as listed, you cannot rely on this for 100%. There's also the issue of having multiple source files even for the main package, supplying them in different order to the compiler may also change the initialization order. The spec has this as a "recommendation":

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

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环境变量.

So to be on the safe side, best would be to set the TZ environment variable before the Go app is launched.

这篇关于在Golang中全局设置时区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆