这些关于 Golang timezone 时区的坑, 我已经帮你踩过了

Golang 中一些不太注意的时区问题

time/tzdata

Golang 内置的一个时区文件。

main.go
import (
	_ "time/tzdata"
)
复制代码

在老版本(1.15)以前并不包含时区信息, 通常会在容器化的时候单独处理时区问题。

FROM golang:alpine as build
RUN apk --no-cache add tzdata
WORKDIR /app
ADD . .
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp

FROM scratch as final
COPY --from=build /app/myapp .
COPY --from=build /usr/share/zoneinfo /usr/share/zoneinfo
ENV TZ=Europe/Berlin
CMD ["/myapp"]
复制代码
time.Parsetime.ParseInLocation
time.ParseUTCtime.ParseInLocation
func timeStr2Time() {
	timeStr := "2023-01-09 22:13:17"
	// 返回的是UTC时间 
    // 2023-01-09 22:13:17 +0000 UTC  
	utcTimeObj, err := time.Parse("2006-01-02 15:04:05", timeStr)
	if err == nil {
		fmt.Println("time.Parse", utcTimeObj, utcTimeObj.Unix())
	}

	// 返回的是当地时间 
    // 2023-01-09 22:13:17 +0800 CST
	localTimeObj, err := time.ParseInLocation("2006-01-02 15:04:05", timeStr, time.Local)
	if err == nil {
		fmt.Println("time.ParseLocation", localTimeObj, localTimeObj.Unix())
	}
}
复制代码

3. 内部时区管理

time.UTC()time.Local()LoadLocation(name)In(loc)
func setTimezone() {


	n1.UTC()      // 转换为 UTC 时区
	n1.Local()    // 转换为 本地时区

	n1.Location() // 返回当前时间时区

	// 没怎么用过
	// loc := time.LoadLocationFromTZData()

	loc2, _ := time.LoadLocation("Asia/Shanghai")
	n1 := time.Now().In(loc2)
	fmt.Println(n1)
}
复制代码

4. 通过代码设置时区

实践操作不允许 通过 代码程序 本身设置时区的。

上面提到的 不允许, 说明

  1. 行为上 可以通过代码设置时区。
  2. 事实上 无法控制结果。

4.1 通过环境变量设置时区

可以通过设置 环境变量 的方式, 设置程序时区。

// $ date # 本地时区 CST
// Mon Jan  9 23:43:03 CST 2023
func setTimezone() {

	os.Setenv("TZ", "UTC")
	fmt.Println(time.Now())
// 2023-01-09 15:42:51.309248 +0000 UTC m=+0.000084251
}
复制代码

但是, 之后就 再也无法改变 时区了。

func setTimezone() {

	os.Setenv("TZ", "UTC")
	fmt.Println(time.Now())

	os.Setenv("TZ", "Asia/Shanghai")
	fmt.Println(time.Now())
}

// 注意看第二个时间也是 UTC 时间
// 2023-01-09 15:46:41.130211 +0000 UTC m=+0.000180001
// 2023-01-09 15:46:41.130284 +0000 UTC m=+0.000253042
复制代码

不仅如此, 如果之前执行过时间命令, 那么 即使第一次设置 时区也是无效的。


func setTimezone() {

	fmt.Println(time.Now())

	os.Setenv("TZ", "UTC")
	fmt.Println(time.Now())

}

// 2023-01-09 23:48:52.72857 +0800 CST m=+0.000167418
// 2023-01-09 23:48:52.729103 +0800 CST m=+0.000696960
复制代码

总结, 时间操作的顺序会 影响 时区的设置。

设置时区

TZ
export TZ=Asia/Shanghai
复制代码

除此之外, 还没找到其它好的办法。

互相吹捧, 共同进步

欢迎和我一起学习进步:可以在掘金私信我

DevOpsCamp星球 是一个完全免费的学习星球。 每月1日和15日 发布作业和扩展阅读文章。 其存在的意义是 帮助和引导 那些愿意学习的人。 想睡的人叫不醒, 想走的人留不住

也可以加我微信号:老麦 , 公众号:Go与云原生 , 关注B站视频:老麦胖熊猫