这些关于 Golang timezone 时区的坑, 我已经帮你踩过了 |
您所在的位置:网站首页 › window时区设置 › 这些关于 Golang timezone 时区的坑, 我已经帮你踩过了 |
这些关于 Golang timezone 时区的坑, 我已经帮你踩过了
原文链接: tangx.in/posts/2023/… Golang 中一些不太注意的时区问题 1. time/tzdata 库Golang 内置的一个时区文件。 可以在程序中任意位置被导入。 导入后, 如果程序 找不到本地 时区文件, 就会使用该库的数据。 本地 指的是 运行环境, 可能是实际的服务器, 也可能是容器。 通常, 应该在 main.go 中被导入。 如果是 库代码 则 不应该 导入该文件。 导入该文件后, 程序会增加 450KB 大小。 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"] 2. time.Parse and time.ParseInLocation 使用 time.Parse 解析时间, 默认 时区是 UTC。 使用 time.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. 内部时区管理 默认情况下, 程序使用 程序运行的本地时区 Go提供了两个函数快速转换 时区 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. 通过代码设置时区在 实践操作 中 不允许 通过 代码 为 程序 本身设置时区的。 上面提到的 不允许, 说明 行为上 可以通过代码设置时区。 事实上 无法控制结果。 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站视频:老麦胖熊猫 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |