time.Sub () возвращает 1 секунду, несмотря на разницу, превышающую пару лет - PullRequest
0 голосов
/ 26 февраля 2020

Я пытаюсь написать фрагмент кода, который будет реагировать на изменение системного времени из-за синхронизации. Вот довольно простой код, который выполняется внутри goroutine:

var start, end time.Time
var start_ts, end_ts int64
var diff_ts time.Duration
var diff time.Duration

for {
    start = time.Now()
    start_ts = start.Unix()
    fmt.Printf("Now: => %v (%d);\n", start, start_ts)
    time.Sleep(1 * time.Second)
    end = time.Now()
    end_ts = end.Unix()
    fmt.Printf("New Now: %v (%d);\n", end, end_ts)
    diff = end.Sub(start)
    diff_ts = time.Duration(end_ts-start_ts) * time.Second
    fmt.Printf("Measured time duration: %v (%v) %f (%f)\n", diff, diff_ts, diff.Seconds(), diff_ts.Seconds())
}

Моя проблема в том, что когда я меняю системное время в другой консоли, время читается правильно, однако «оригинальная» разница во времени неверна и Я должен прибегнуть к построению разницы во времени вручную. Вот выдержка из журналов:

Now: => 2020-02-26 12:29:42.778827718 +0000 UTC m=+21.776791756 (1582720182);
New Now: 2017-01-01 01:02:03.391215325 +0000 UTC m=+22.777003266 (1483232523);
Measured time duration: 1.00021151s (-27635h27m39s) 1.000212 (-99487659.000000)

почему объект diff возвращает 1 секунду, даже если разница явно больше, чем эта?

1 Ответ

2 голосов
/ 26 февраля 2020
Пакет времени

go использует как "настенные часы" (что вы пытаетесь изменить), так и однотонные c часы. Из документов :

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

[...]

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

Это специально разработано для предотвращения отклонения в поведении приложения, когда происходит синхронизация часов c (ntp et c.) (И толкает часы назад). Пакет времени go гарантирует, что монотонное c показание часов всегда движется вперед (при операциях сравнения или вычитания).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...