вторник, 21 июля 2020 г.

Пакет time в Golang, монотонные часы

Пакет time обеспечивает функциональность для измерения и отображения времени.

Календарные вычисления всегда предполагают григорианский календарь, без високосных секунд.

Монотонные часы

Операционные системы предоставляют как "настенные часы", которые могут быть изменены для синхронизации часов, так и "монотонные часы", которые не могут быть изменены для синхронизации часов. Общее правило заключается в том, что настенные часы предназначены для определения времени, а монотонные часы - для измерения времени. Вместо того, чтобы разделять API, в этом пакете Time, возвращаемое time.Now содержит как чтение настенных часов, так и чтение монотонных часов; в более поздних операциях с указанием времени используется считывание настенных часов, а в более поздних операциях измерения времени, в частности сравнения и вычитания, используется монотонное считывание часов.

Например, этот код всегда вычисляет положительное прошедшее время, равное приблизительно 20 миллисекундам, даже если настенные часы меняются во время рассчитываемой операции:

start := time.Now()
... операция, которая занимает 20 миллисекунд ...
t := time.Now()
elapsed := t.Sub(start)

Другие идиомы, такие как time.Since(start), time.Until(deadline), и time.Now().Before(deadline), одинаково устойчивы к сбросам настенных часов.

В оставшейся части этого поста приводятся точные сведения о том, как в операциях используются монотонные часы.

Время, возвращаемое time.Now содержит монотонное чтение часов. Если время t имеет монотонные показания часов, t.Add добавляет одинаковую длительность как к настенным часам, так и к показаниям монотонных часов, чтобы вычислить результат. Поскольку t.AddDate(y, m, d), t.Round(d) и t.Truncate(d) являются вычислениями времени по настенным часам, они всегда удаляют любые монотонные показания часов из своих результатов. Поскольку t.In, t.Local и t.UTC используются для их влияния на интерпретацию настенного времени, они также удаляют любые монотонные показания часов из своих результатов. Канонический способ снять монотонное чтение часов - использовать t = t.Round(0).

Если времена t и u содержат монотонные показания часов, операции t.After(u), t.Before(u), t.Equal(u) и t.Sub(u) выполняются с использованием только монотонных показаний часов, игнорируя показания настенных часов. Если ни t, ни u не содержат монотонных показаний часов, эти операции сводятся к использованию показаний настенных часов.

В некоторых системах монотонные часы остановятся, если компьютер перейдет в спящий режим. В такой системе t.Sub(u) может не точно отражать фактическое время, прошедшее между t и u.

Поскольку монотонное чтение часов не имеет смысла вне текущего процесса, сериализованные формы, сгенерированные t.GobEncode, t.MarshalBinary, t.MarshalJSON и t.MarshalText, опускают монотонное чтение часов, и t.Format не предоставляет для него никакого формата. Аналогично, конструкторы time.Date, time.Parse, time.ParseInLocation и time.Unix, а также демаршалеры t.GobDecode, t.UnmarshalBinary. t.UnmarshalJSON и t.UnmarshalText всегда создают времена без монотонного чтения часов.

Обратите внимание, что оператор Go == сравнивает не только момент времени, но и местоположение и показания монотонных часов.

Для отладки результат t.String включает монотонное чтение часов, если оно присутствует. Если t != u из-за различных монотонных показаний часов, эта разница будет видна при печати t.String() и u.String().


Читайте также:


Комментариев нет:

Отправить комментарий