go - 为什么 Go time.Format 会根据时区返回不同的值?
问题描述
我认为 Go time.Format应该根据布局格式化时间。但似乎它根据时区信息返回不同的值。
package main
import (
"fmt"
"time"
)
func main() {
formats := []string{
time.RFC3339,
}
times := []string{
"2020-03-08T01:59:50-08:00",
"2020-03-08T01:59:59-08:00", //daylight saving starts 1 second later
"2020-03-08T05:59:59-08:00",
}
for _, f := range formats {
for _, t := range times {
fmt.Printf("Format: %s\n", f)
t, err := time.Parse(f, t)
if err != nil {
panic(err)
}
fmt.Printf("unix: %d\n", t.UnixNano())
fmt.Printf("time: %s\n", t.Format(f))
t = t.Add(time.Second)
fmt.Printf("time + 1s: %s\n", t.Format(f))
}
}
}
运行输出:
➜ go version
go version go1.15 darwin/amd64
➜ TZ=UTC go run main.go
Format: 2006-01-02T15:04:05Z07:00
unix: 1583661590000000000
time: 2020-03-08T01:59:50-08:00
time + 1s: 2020-03-08T01:59:51-08:00
Format: 2006-01-02T15:04:05Z07:00
unix: 1583661599000000000
time: 2020-03-08T01:59:59-08:00
time + 1s: 2020-03-08T02:00:00-08:00 (a: this is not expected)
unix: 1583675999000000000
time: 2020-03-08T05:59:59-08:00
time + 1s: 2020-03-08T06:00:00-08:00
➜ TZ=America/Los_Angeles go run main.go
Format: 2006-01-02T15:04:05Z07:00
unix: 1583661590000000000
time: 2020-03-08T01:59:50-08:00
time + 1s: 2020-03-08T01:59:51-08:00
Format: 2006-01-02T15:04:05Z07:00
unix: 1583661599000000000
time: 2020-03-08T01:59:59-08:00
time + 1s: 2020-03-08T03:00:00-07:00 (b: this is expected)
Format: 2006-01-02T15:04:05Z07:00
unix: 1583675999000000000
time: 2020-03-08T05:59:59-08:00
time + 1s: 2020-03-08T06:00:00-08:00 (c: this contradicts with the b)
解决方案
该行为已记录在案。的输出time.Format
只是一个结果,而不是混淆的来源——即time.Parse
:
函数解析:
在解析具有 -0700 之类的区域偏移量的时间时,如果偏移量对应于当前位置 (Local) 使用的时区,则 Parse 在返回的时间中使用该位置和区域。否则,它将时间记录为在一个虚构的位置,时间固定在给定的区域偏移。
进一步的解释可以在 Location 类型下找到:
Local 表示系统的本地时区。在 Unix 系统上,Local 查询 TZ 环境变量以查找要使用的时区。无 TZ 表示使用系统默认的 /etc/localtime。TZ="" 表示使用 UTC。TZ="foo" 表示使用系统时区目录中的文件 foo。
基本上,go 的解析器尝试从 UTC 偏移量推断时区。如果解析后的 UTC 偏移量与TZ
环境变量设置的时区匹配,则在返回的time
. 在处理日期和时间时,简单似乎总是结束。
推荐阅读
- ssl - 找不到 ngrok websocket 安全的证书
- php - (PHP) 带有授权标头的 file_get_contents
- django - 在 Django DetailView 中比较两个模型的值
- php - 如何通过 php 使用 Festival 文本到语音
- ms-access - Access 2016 如何使用变量的值而不是变量?
- ruby-on-rails - 未初始化的常量 ApplicationController (NameError)
- autodesk-model-derivative - Autodesk Forge 模型衍生 API:TranslationWorker-InternalFailure
- python - 无法使用折线图进行可视化
- rust - 从“拉”提交的索引写入树时,来自 libgit2 的“索引不受存储库支持”错误
- javascript - 带有 discord.js 的 node.js 中反应的多个输出