Помилки програмістів про Unix-часу

Приношу вибачення Патріку МакКензі.

Вчора Денні поцікавився цікавими фактами про Unix-час, а я згадав, що іноді він працює зовсім неінтуїтивно.

Ось ці три факти здаються дуже розумними і логічними, чи не так?

  1. Час Unix - це кількість секунд з 1 січня 1970 00:00:00 UTC.
  2. Якщо зачекати рівно одну секунду, то час Unix зміниться рівно одну секунду.
  3. Час Unix ніколи не рухається назад.

Все це неправда.

Але недостатньо просто заявити "Все це неправда", не пояснивши, чому. Пояснення див. нижче. Але якщо хочете самі подумати, не прокручуйте зображення годинника!

Помилки програмістів про Unix-часу
Настільний годинник 1770-х років. Зібрано Джоном Леру. З колекції Wellcome. Опубліковано під ліцензією CC BY

У всіх трьох помилок одна причина: високосні секунди. Якщо ви не знайомі з додатковими секундами, ось коротка довідка:

Час UTC визначається двома факторами:

  • Міжнародний атомний час: усереднені показання сотень атомних годинників по всьому світу. Ми можемо виміряти секунду за електромагнітними властивостями атома, і це найточніший вимір часу, відомий науці.
  • Всесвітній час, заснований на обертанні Землі навколо своєї осі. Один повний оборот – одна доба.

Проблема в тому, що ці два числа не завжди збігаються. Обертання Землі не є послідовним — воно поступово сповільнюється, тому доба у Всесвітньому часі стає довшою. З іншого боку, атомний годинник диявольськи точний і постійний протягом мільйонів років.

Коли два часи випадають із синхрону, UTC додається або видаляється секунда, щоб повернути синхронізацію. З 1972 року служба IERS (яка управляє цією справою) додала 27 додаткових секунд. В результаті вийшло 27 діб UTC тривалістю 86 401 секунду. Теоретично можлива поява доби тривалістю 86 секунд (мінус одна). Обидва варіанти суперечать фундаментальному припущенню про Unix-час.

Час Unix передбачає, що щодня триває рівно 86 400 секунд (60 60 24 = 86 400), без будь-яких додаткових секунд. Якщо відбувається такий стрибок, то час Unix або перестрибує за секунду, або відраховуючи дві секунди за одну. Станом на 2019 рік у ньому немає 27 високосних секунд.

Тож наші помилки потрібно доповнити таким чином:

  • Час Unix - це кількість секунд з 1 січня 1970 00:00:00 UTC мінус високосні секунди.
  • Якщо зачекати рівно одну секунду, час Unix зміниться рівно одну секунду, якщо не було видалено додаткову секунду.

    Досі на практиці секунди ніколи не видалялися (і уповільнення обертання Землі означає, що це малоймовірно), але якби це колись сталося, це означало б, що день UTC став на одну секунду коротшим. В цьому випадку остання секунда UTC (23:59:59) відкидається.

    У кожну добу Unix однакова кількість секунд, тому остання Unix-секунда вкороченого дня не буде відповідати жодному часу UTC. Ось як це виглядає, в інтервалах по чверті секунди:

    Помилки програмістів про Unix-часу

    Якщо стартувати о 23:59:58:00 UTC і зачекати одну секунду, час Unix просунеться на дві секунди UTC, а мітка часу Unix 101 нікому не призначається.

  • Час Unix ніколи не може повернутися назад, доки не додана додаткова секунда.

    Це вже 27 разів сталося практично. Після закінчення доби UTC додають додаткову секунду 23:59:60. У добі Unix однакова кількість секунд, тому він не може додати додаткову секунду - натомість доводиться повторювати мітки часу Unix для останньої секунди. Ось як це виглядає, в інтервалах по чверті секунди:

    Помилки програмістів про Unix-часу

    Якщо стартувати о 23:59:60.50 і зачекати півсекунди, то час Unix повертається на півсекунди, а позначка часу Unix 101 відповідає двом секундам UTC.

Ймовірно, це не єдина дивина часу Unix — тільки те, що я вчора згадав.

Час - дуже дивна річ.

Джерело: habr.com

Додати коментар або відгук