1. 时间与时区

1.1 时间标准

UTC,世界标准时间,是现在的时间标准,以原子时计时。

GMT,格林威治时间,是以前的时间标准,规定太阳每天经过位于英国伦敦郊区的皇家格林威治天文台的时间为中午 12 点。

UTC 时间更加准确,但如果对精度要求不高,可以视两种标准等同。

1.2 时区划分

从格林威治本初子午线起,经度每向东或者向西间隔 15°,就划分一个时区,因此一共有 24 个时区,东、西个 12 个。

  • UTC-6(CST — 北美中部标准时间)
  • UTC+9(JST — 日本标准时间)
  • UTC+8(CT/CST — 中原标准时间)
  • UTC+5:30(IST — 印度标准时间)
  • UTC+3(MSK — 莫斯科时区)

1.3 Local 时间

Local 时间为当前系统的带时区时间,可以通过 /etc/localtime 获取。实际上 /etc/localtime 是指向 zoneinfo 目录下的某个时区。下面是 MacOS 上的执行结果,Linux 上的路径会不一样:

2. Go 中的时间及序列化

2.1 Go 如何初始化时区

  1. 查找 TZ 变量获取时区
  2. 如果没有 TZ,那么使用 /etc/localtime
  3. 如果 TZ="",那么使用 UTC
  4. 当 TZ=“foo” 或者 TZ=":foo"时,如果 foo 指向的文件将被用于初始化时区,否则使用 /usr/share/zoneinfo/foo

下面是 Go 实现的源码:

2.2 Go 时间字段的序列化

在 Go 使用 “encoding/json” 可以对 Time 字段进行序列化,使用 Format 可以对时间格式进行自定义。如下示例:

输出结果:

2021-12-07 16:44:44.874809 +0800 CST m=+0.000070010

"2021-12-07T16:44:44.874937+08:00"

"Tue, 07 Dec 2021 16:44:44 CST"

"00-120-74 16:44:07"

"21-12-07"

2.3 Go 结构体中的时间字段序列化

在结构体中,如果直接使用 “encoding/json” 对结构体进行序列化,得到的将会是这样的时间格式: 2021-12-07T17:31:08.811045+08:00。无法使用 Format 函数对时间格式进行控制。

那么,如何控制结构体中的时间格式呢?请看如下示例:

输出结果:

{"title":"this is title","time":"2021-12-07T17:31:08.811045+08:00"}

{"title":"this is title","time":"Tue, 07 Dec 2021 17:31:08 +0800"}

这里主要是使用 “github.com/json-iterator/go” 包控制 Go 对时间字段的序列化,通过其提供的扩展指定 key 为 startedat、finishedat 的时间字段,指定序列化时使用 timeFormat := time.RFC1123Z 格式和 locale, _ := time.LoadLocation("Asia/Shanghai") 时区。

3. 各种环境下设置时区

3.1 在 Linux 中

执行命令:

或者设置 TZ 环境变量:

都可以设置时区。

3.1 在 Docker 中

在制作镜像时,直接在 Dockerfile 设置 TZ 变量,可能会碰到问题:

报错: panic: time: missing Location in call to Time.In

原因: 我们常用的 Linux 系统,例如 Ubuntu、CentOS,在 /usr/share/zoneinfo/ 目录下存放了各个时区而 alpine 镜像没有。

因此 alpine 镜像需要安装一些额外的包。

在运行容器时,可以直接挂载主机的时区描述文件:

3.2 在 Kubernetes 中

这里将主机上的时区文件挂载到 Pod 中。

4. 参考

https://github.com/json-iterator/go

5.golang时区处理

如果要设定时区,那么在使用时间函数之前,就要设定时区。

那么问题就来了,打个比喻说。我想在墨西哥5月6号12点45分时开始促销。而我在中国,那么你要设定了个什么样的数字呢?

墨西哥是西5时区-5,中国是+8时区,相差13个时区,也就是在中国今天是5.6号,那么墨西哥是5.5号

也就是说,我今天要设置5.7号的时间吗?

。。。。。。。。。。。。。

其实我觉得,是不是直接设定5.6号就行了。因为设定了,那么墨西哥是5.6号做的促销,你只要在5.7号跟进就行了。

如果你想要看交易数据(按照中国的时间来看),那样才要做转换。也就是中国时间5.7号,墨西哥卖出了多少货。

好了,不扯蛋了。下面是有需要转时区的写法。

总结

原文链接:https://www.chenshaowen.com/blog/the-tips-of-time-and-tz-in-go.html