Go on Linux 和 macOS 中 RFC3339 的时间格式化结果不同
The result of time formatting of RFC3339 in Go on Linux and macOS are different
我运行下面的go代码。
package main
import (
"fmt"
"strconv"
"time"
)
func main() {
i, err := strconv.ParseInt("1405544146", 10, 64)
if err != nil {
panic(err)
}
tm := time.Unix(i, 0).Format(time.RFC3339)
fmt.Println(tm)
fmt.Println(time.RFC3339)
}
那么Linux的结果是
2014-07-16T20:55:46Z
2006-01-02T15:04:05Z07:00
在 macOS 上是
2014-07-17T05:55:46+09:00
2006-01-02T15:04:05Z07:00
时间相同,但格式化后的结果不同。你知道原因吗?
不要仓促下结论。检查所有证据。例如,考虑本地时区。
import "time"
func Unix(sec int64, nsec int64) Time
Unix returns the local Time corresponding to the given Unix time, sec
seconds and nsec nanoseconds since January 1, 1970 UTC.
例如,
package main
import (
"fmt"
"runtime"
"strconv"
"time"
)
func main() {
i, err := strconv.ParseInt("1405544146", 10, 64)
if err != nil {
panic(err)
}
t := time.Unix(i, 0)
fmt.Println(t)
fmt.Println(t.Format(time.RFC3339))
fmt.Println(time.RFC3339)
fmt.Println(runtime.GOOS, runtime.GOARCH, runtime.Version())
}
游乐场:https://play.golang.org/p/UH6o57YckiV
输出(游乐场):
2014-07-16 20:55:46 +0000 UTC
2014-07-16T20:55:46Z
2006-01-02T15:04:05Z07:00
nacl amd64p32 go1.12
输出(Linux):
2014-07-16 16:55:46 -0400 EDT
2014-07-16T16:55:46-04:00
2006-01-02T15:04:05Z07:00
linux amd64 devel +5b68cb65d3 Thu Mar 28 23:49:52 2019 +0000
不同的时区(UTC 与 EDT)因此日期和时间的格式不同。
在您的示例中,您有 2014-07-16T20:55:46Z
和 2014-07-17T05:55:46+09:00
,不同的时区因此具有不同格式的日期和时间。
2014-07-16T20:55:46Z
和2014-07-17T05:55:46+09:00
不同时区时间。
time.RFC3339 是常量。 https://golang.org/pkg/time/#RFC3339.
const (
// ...
RFC3339 = "2006-01-02T15:04:05Z07:00"
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
// ...
)
go 使用数字时间或 Z 触发 ISO 8601。
数字时区偏移格式如下:
-0700 ±hhmm
-07:00 ±hh:mm
-07 ±hh
并且用 Z 替换格式中的符号会触发打印 Z 的 ISO 8601 行为,而不是 UTC 区域的偏移量。
Z0700 Z or ±hhmm
Z07:00 Z or ±hh:mm
Z07 Z or ±hh
两个不同的 OS 对同一输入产生不同输出的原因是 OS 的时区 配置 。 Linux 框中的时区似乎 未 已设置。
go
将尝试从本地 OS 获取时区。如果不可用,则默认为 UTC
。如果您想从 MacOS 和 Linux 获得一致的输出 - 确保时区相同。要明确执行此操作,请设置 TZ
环境变量。这将适用于 Linux 和 MacOS 等
$ go build -o gotime ./main.go
$ uname -s
Linux
$ TZ=CET ./gotime
2014-07-16T22:55:46+02:00
2006-01-02T15:04:05Z07:00
$ TZ="" ./gotime
2014-07-16T20:55:46Z
2006-01-02T15:04:05Z07:00
$ uname -s
Darwin
$ TZ=CET ./gotime
2014-07-16T22:55:46+02:00
2006-01-02T15:04:05Z07:00
$ TZ="" ./gotime
2014-07-16T20:55:46Z
2006-01-02T15:04:05Z07:00
这个问题是由于golang上的时间位置问题。
Linuxgolang 的默认时间位置是"UTC",MacOS golang 是"Local"。
("Local" 使用 os 的时间位置。)
您可以查看时间地点。
fmt.Println(time.Local) // Result of MacOS is "Local"
如果您想从 MacOS 获得 "UTC" 结果,您应该使用 "In" 函数。
lo, _ := time.LoadLocation("UTC")
tmUTC := time.Unix(1405544146, 0).In(lo).Format(time.RFC3339)
如果你 运行 在 MacOS 上编写代码,你可以获得类似 linux 的结果。
i, err := strconv.ParseInt("1405544146", 10, 64)
if err != nil {
panic(err)
}
tm := time.Unix(i, 0).Format(time.RFC3339)
fmt.Println(tm)
lo, _ := time.LoadLocation("UTC")
tmUTC := time.Unix(i, 0).In(lo).Format(time.RFC3339)
我运行下面的go代码。
package main
import (
"fmt"
"strconv"
"time"
)
func main() {
i, err := strconv.ParseInt("1405544146", 10, 64)
if err != nil {
panic(err)
}
tm := time.Unix(i, 0).Format(time.RFC3339)
fmt.Println(tm)
fmt.Println(time.RFC3339)
}
那么Linux的结果是
2014-07-16T20:55:46Z
2006-01-02T15:04:05Z07:00
在 macOS 上是
2014-07-17T05:55:46+09:00
2006-01-02T15:04:05Z07:00
时间相同,但格式化后的结果不同。你知道原因吗?
不要仓促下结论。检查所有证据。例如,考虑本地时区。
import "time"
func Unix(sec int64, nsec int64) Time
Unix returns the local Time corresponding to the given Unix time, sec seconds and nsec nanoseconds since January 1, 1970 UTC.
例如,
package main
import (
"fmt"
"runtime"
"strconv"
"time"
)
func main() {
i, err := strconv.ParseInt("1405544146", 10, 64)
if err != nil {
panic(err)
}
t := time.Unix(i, 0)
fmt.Println(t)
fmt.Println(t.Format(time.RFC3339))
fmt.Println(time.RFC3339)
fmt.Println(runtime.GOOS, runtime.GOARCH, runtime.Version())
}
游乐场:https://play.golang.org/p/UH6o57YckiV
输出(游乐场):
2014-07-16 20:55:46 +0000 UTC
2014-07-16T20:55:46Z
2006-01-02T15:04:05Z07:00
nacl amd64p32 go1.12
输出(Linux):
2014-07-16 16:55:46 -0400 EDT
2014-07-16T16:55:46-04:00
2006-01-02T15:04:05Z07:00
linux amd64 devel +5b68cb65d3 Thu Mar 28 23:49:52 2019 +0000
不同的时区(UTC 与 EDT)因此日期和时间的格式不同。
在您的示例中,您有 2014-07-16T20:55:46Z
和 2014-07-17T05:55:46+09:00
,不同的时区因此具有不同格式的日期和时间。
2014-07-16T20:55:46Z
和2014-07-17T05:55:46+09:00
不同时区时间。
time.RFC3339 是常量。 https://golang.org/pkg/time/#RFC3339.
const (
// ...
RFC3339 = "2006-01-02T15:04:05Z07:00"
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
// ...
)
go 使用数字时间或 Z 触发 ISO 8601。
数字时区偏移格式如下:
-0700 ±hhmm
-07:00 ±hh:mm
-07 ±hh
并且用 Z 替换格式中的符号会触发打印 Z 的 ISO 8601 行为,而不是 UTC 区域的偏移量。
Z0700 Z or ±hhmm
Z07:00 Z or ±hh:mm
Z07 Z or ±hh
两个不同的 OS 对同一输入产生不同输出的原因是 OS 的时区 配置 。 Linux 框中的时区似乎 未 已设置。
go
将尝试从本地 OS 获取时区。如果不可用,则默认为 UTC
。如果您想从 MacOS 和 Linux 获得一致的输出 - 确保时区相同。要明确执行此操作,请设置 TZ
环境变量。这将适用于 Linux 和 MacOS 等
$ go build -o gotime ./main.go
$ uname -s
Linux
$ TZ=CET ./gotime
2014-07-16T22:55:46+02:00
2006-01-02T15:04:05Z07:00
$ TZ="" ./gotime
2014-07-16T20:55:46Z
2006-01-02T15:04:05Z07:00
$ uname -s
Darwin
$ TZ=CET ./gotime
2014-07-16T22:55:46+02:00
2006-01-02T15:04:05Z07:00
$ TZ="" ./gotime
2014-07-16T20:55:46Z
2006-01-02T15:04:05Z07:00
这个问题是由于golang上的时间位置问题。
Linuxgolang 的默认时间位置是"UTC",MacOS golang 是"Local"。 ("Local" 使用 os 的时间位置。)
您可以查看时间地点。
fmt.Println(time.Local) // Result of MacOS is "Local"
如果您想从 MacOS 获得 "UTC" 结果,您应该使用 "In" 函数。
lo, _ := time.LoadLocation("UTC")
tmUTC := time.Unix(1405544146, 0).In(lo).Format(time.RFC3339)
如果你 运行 在 MacOS 上编写代码,你可以获得类似 linux 的结果。
i, err := strconv.ParseInt("1405544146", 10, 64)
if err != nil {
panic(err)
}
tm := time.Unix(i, 0).Format(time.RFC3339)
fmt.Println(tm)
lo, _ := time.LoadLocation("UTC")
tmUTC := time.Unix(i, 0).In(lo).Format(time.RFC3339)