После сохранения я получил бы имя зоны и смещение, используя Time.Zone()
:
func (t Time) Zone() (name string, offset int)
Затем при запросе такой временной метки из базы данных вы можете построить time.Location
, используя time.FixedZone()
:
func FixedZone(name string, offset int) *Location
И переключитесь в это местоположение, используя Time.In()
.
Предостережение! Это восстановит вам временную метку с «на первый взгляд» в том же часовом поясе, но если вам нужно применить к нему операции (например, добавить дни), результаты могут не совпадать,Причина этого заключается в том, что time.FixedZone()
возвращает часовой пояс с фиксированным смещением, который, например, ничего не знает о переходе на летнее время , тогда как исходная сохраненная вами временная метка может иметь time.Location
, который знаетоб этих вещах.
Вот пример такого отклонения.В марте наступает переход на летнее время, поэтому мы будем использовать метку времени, указывающую на 1 марта, и добавим к ней 1 месяц, в результате чего метка времени будет после летнего времени.
cet, err := time.LoadLocation("CET")
if err != nil {
panic(err)
}
t11 := time.Date(2019, time.March, 1, 12, 0, 0, 0, cet)
t12 := t11.AddDate(0, 1, 0)
fmt.Println(t11, t12)
name, offset := t11.Zone()
cet2 := time.FixedZone(name, offset)
t21 := t11.UTC().In(cet2)
t22 := t21.AddDate(0, 1, 0)
fmt.Println(t21, t22)
now := time.Date(2019, time.April, 2, 0, 0, 0, 0, time.UTC)
fmt.Println("Time since t11:", now.Sub(t11))
fmt.Println("Time since t21:", now.Sub(t21))
fmt.Println("Time since t12:", now.Sub(t12))
fmt.Println("Time since t22:", now.Sub(t22))
Это будетвыходной сигнал (попробуйте на Go Playground ):
2019-03-01 12:00:00 +0100 CET 2019-04-01 12:00:00 +0200 CEST
2019-03-01 12:00:00 +0100 CET 2019-04-01 12:00:00 +0100 CET
Time since t11: 757h0m0s
Time since t21: 757h0m0s
Time since t12: 14h0m0s
Time since t22: 13h0m0s
Как видите, время вывода после добавления в 1 месяц такое же, но смещение зоны другое,поэтому они обозначают другой момент времени во времени (что подтверждается показом разницы во времени с произвольным временем).Оригинал имеет смещение на 2 часа, потому что он знает о переходе на летнее время, которое произошло за 1 месяц, который мы пропустили, в то время как зона «восстановленной» временной метки не знает об этом, поэтому результат имеет то же смещение на 1 час.В метке времени после добавления даже имя зоны изменяется в реальной жизни: с CET
до CEST
, и опять же, зона восстановленной метки времени также не знает об этом.