Результат форматирования времени RFC3339 в Go на Linux и macOS различен - PullRequest
2 голосов
/ 29 марта 2019

Я запустил следующий код.

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

Это то же самое время, но отформатированные результаты отличаются. Вы знаете причину?

Ответы [ 4 ]

1 голос
/ 29 марта 2019

2014-07-16T20:55:46Z и 2014-07-17T05:55:46+09:00 различное время зоны.

время. 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 запускает поведение печати по ISO 8601 вместо смещения для зоны UTC.

Z0700  Z or ±hhmm
Z07:00 Z or ±hh:mm
Z07    Z or ±hh
1 голос
/ 29 марта 2019

Не спешите с выводами. Изучите все доказательства. Например, рассмотрим местный часовой пояс.

Пакетное время

import "time" 

func Unix

func Unix(sec int64, nsec int64) Time

Unix возвращает местное время, соответствующее заданному времени Unix, сек секунды и нсек наносекунды с 1 января 1970 года по Гринвичу.


Например,

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, разные часовые пояса, поэтому разные даты и время в формате.

0 голосов
/ 30 марта 2019

Эта проблема связана с временным местоположением на Голанге.

Местоположение по умолчанию для Linux golang - «UTC», а для MacOS - «Local». («Локальное» использование времени расположения ос.)

Вы можете проверить время нахождения.

fmt.Println(time.Local) // Result of MacOS is "Local"

Если вы хотите получить результаты «UTC» из MacOS, вам следует использовать функцию «В».

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)
0 голосов
/ 29 марта 2019

Причина, по которой две разные ОС дают разные выходы для одного и того же входа, заключается в том, что часовой пояс ОС конфигурация .Похоже, что часовой пояс на компьютере Linux не установлен.

go попытается выбрать часовой пояс из локальной ОС.Если недоступно, по умолчанию используется 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
...