为什么Go time.Format根据时区返回不同的值? [英] Why does Go time.Format return different value based on timezone?

查看:76
本文介绍了为什么Go time.Format根据时区返回不同的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为Go time.Format 应该根据布局来格式化时间.但似乎它会根据时区信息返回不同的值.

I thought the Go time.Format should format time based on the layout. But seems it returns different value based on timezone info.

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 :

The behavior is documented. The output of time.Format is just a consequence, not the confusion's source - which is time.Parse:

功能解析 :

当解析时间偏移为-0700的时间时,如果偏移量对应于当前位置(本地)使用的时区,然后解析在返回的时间中使用该位置和区域.否则将时间记录为在伪造位置,时间固定为给定的区域偏移量.

When parsing a time with a zone offset like -0700, if the offset corresponds to a time zone used by the current location (Local), then Parse uses that location and zone in the returned time. Otherwise it records the time as being in a fabricated location with time fixed at the given zone offset.

进一步的解释可以在下面找到 输入位置 :

Further explanation can be found under type Location:

Local表示系统的本地时区.在Unix系统上,本地查阅TZ环境变量以找到要使用的时区.不TZ表示使用系统默认的/etc/localtime.TZ =".表示使用UTC.TZ ="foo";表示在系统时区目录中使用文件foo.

Local represents the system's local time zone. On Unix systems, Local consults the TZ environment variable to find the time zone to use. No TZ means use the system default /etc/localtime. TZ="" means use UTC. TZ="foo" means use file foo in the system timezone directory.

基本上,go的解析器尝试从UTC偏移量推断时区.如果解析的UTC偏移与 TZ 环境变量设置的时区相匹配,则在返回的 time 中设置该时区.在处理日期和时间方面,简单性似乎总是​​会结束.时间.

Basically, go's parser tries to infer a time zone from a UTC offset. If the parsed UTC offset matches that of the time zone set by the TZ environment variable, this time zone is set in the returned time. Simplicity always seems to end when it comes to handling date & time.

这篇关于为什么Go time.Format根据时区返回不同的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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