Почему время. Пара не использует часовой пояс? - PullRequest
0 голосов
/ 11 мая 2018

Почему time.Parse не использует информацию о часовом поясе?Должно возвращаться разное время для разных часовых поясов.

Код

package main

import (
    "fmt"
    "time"
)

func main() {
    t, err := time.Parse("2006-01-02 MST", "2018-05-11 IST")
    if err != nil {
        return
    }
    t2, err := time.Parse("2006-01-02 MST", "2018-05-11 UTC")
    if err != nil {
        return
    }
    fmt.Println(t.Unix())
    fmt.Println(t2.Unix())
}

Выход:

1525996800
1525996800

1 Ответ

0 голосов
/ 11 мая 2018

Некоторое объяснение самого вопроса:

Эти 2 метки времени 2018-05-11 IST и 2018-05-11 UTC не обозначают один и тот же момент времени, поскольку IST имеет смещение, отличное от UTC: Стандартное время Индии (IST) равно 5:. 30 часов больше, чем универсальное координированное время (UTC)

1006 * И Time.Unix() возвращает истекшие секунды до момента времени, прошедшее с моментом начала отсчета времени (1 января 1970 UTC),Это означает, что вывод должен быть другим!

Запуск вашего кода на PlayGround действительно дает неправильный результат ( ссылка ).

И это проблема, связанная с часовым поясом.Если вы попытаетесь загрузить часовой пояс IST:

loc, err := time.LoadLocation("IST")
fmt.Println(loc, err)

Вывод:

UTC cannot find IST in zip file /usr/local/go/lib/time/zoneinfo.zip

И причина, по которой «IST» не поддерживается, заключается в том, что он неоднозначен.Это могут означать часовые пояса Индии, Ирландии, Израиля и т. Д., Которые имеют разные смещения и правила.

И документация time.Parse() гласит, что

Если аббревиатура зоны неизвестна, Parse записывает время как изготовленное местоположение с данной аббревиатурой зоны и смещением нуля .

Таким образом, time.time возвращаетсяparse.Parse() будет иметь смещение 0 точно так же, как зона UTC, следовательно, это приведет к тому же «времени unix» (Time.Unix() вернет то же значение).

Но запуск его локально (с моим CET)часовой пояс дает другой, правильный результат:

t, err := time.Parse("2006-01-02 MST", "2018-05-11 CET")
if err != nil {
    panic(err)
}
t2, err := time.Parse("2006-01-02 MST", "2018-05-11 UTC")
if err != nil {
    panic(err)
}
fmt.Println(t)
fmt.Println(t2)

fmt.Println(t.Unix())
fmt.Println(t2.Unix())

Вывод:

2018-05-11 01:00:00 +0200 CEST
2018-05-11 00:00:00 +0000 UTC
1525993200
1525996800

Документация time.Parse() имеет это сказать о разборе времени с сокращением зоны:

При разборе времени с аббревиатурой зоны, такой как MST, если аббревиатура зоны имеет определенное смещение в текущем местоположении, то это смещение используется.Аббревиатура зоны «UTC» распознается как UTC независимо от местоположения.Если аббревиатура зоны неизвестна, Parse записывает время как изготовленное местоположение с данной аббревиатурой зоны и нулевым смещением.Этот выбор означает, что такое время может быть проанализировано и переформатировано с той же компоновкой без потерь, но точный момент, используемый в представлении, будет отличаться фактическим смещением зоны.Чтобы избежать таких проблем, предпочитайте временные макеты, которые используют числовое смещение зоны, или используйте ParseInLocation.

Документация предлагает выполнить синтаксический анализ с макетом со смещением числовой зоны, например:

t, err := time.Parse("2006-01-02 -0700", "2018-05-11 +0530")
if err != nil {
    panic(err)
}

Затем выведите (попробуйте на Go Playground ):

2018-05-11 00:00:00 +0530 +0530
2018-05-11 00:00:00 +0000 UTC
1525977000
1525996800

Другой вариант - использовать time.FixedZone() для создания IST самостоятельно, ииспользуйте time.ParseInLocation(), передавая наше руководство IST location:

ist := time.FixedZone("IST", 330*60) // +5:30
t, err := time.ParseInLocation("2006-01-02 MST", "2018-05-11 IST", ist)

Вывод будет (попробуйте на Go Playground ):

2018-05-11 00:00:00 +0530 IST
2018-05-11 00:00:00 +0000 UTC
1525977000
1525996800

Еще один вариант - загрузить индийскую зону IST по городу Калькутта:

loc, err := time.LoadLocation("Asia/Kolkata")
if err != nil {
    panic(err)
}

, что даст тот же результат.Попробуйте на Go Playground .

...