Високосные секунды и трагедия упрямых дураков
Все мы пользуемся шкалой времени UTC в том или ином виде, ибо именно по ней выставляется время в каждом часовом поясе. В её основе лежит время TAI (усреднённое время 450 атомных часов, расположенных по всему миру), что по сути делает эту шкалу максимально точным способом подсчёта времени. Однако есть неприятный ньюанс: длительность солнечных суток (одного оборота Земли вокруг своей оси) не равна 24-м часам (86400 секунд по атомным часам; запомните эту цифру, она нам ещё пригодится). Тем не менее наступление следующего календарного дня мы определяем именно как интервал времени в 24 часа.
Предположим, что время полного оборота Земли вокруг своей оси на одну секунду больше, чем 24 часа по атомным часам. Пусть в первый день рассвет наступает в 6 утра. Во-второй день рассвет наступит в 06 часов 00 минут 01 секунду (давайте для простоты забудем о наклоне земной оси и прочих сложностях, которые могут помешать ухватить нам суть проблемы). В третий день рассвет наступит в 06:00:02. Через какое-то врем мы ошибёмся ровно на 12 часов: заход солнца будет случаться в 6 утра.
К счастью, средняя длительность солнечных суток 2000 года была равна 86400,002 секунды, то есть убегание всего на 2 миллисекунды в год, поэтому проблема накапливается не так быстро, но тем не менее она существует. И если вам показалось, что всё это очень похоже «проблему» с високосным годом, то вы чертовски правы. Только там всё происходит из-за вращения Земли вокруг солнца, которое не равно 365 дням, а тут из-за вращения Земли вокруг своей оси, которое не равно 24-м часам (два независимых вращения, не будем их путать!).
Проблему сдвига времени года решил григорианский календарь 15 октября 1582 года, который ввёл дополнительные сутки в феврале, а проблему времени суток решили введением дополнительной секунды в 1972-м году, которая также называется високосной секундой или секундой координации. Если говорить совсем грубо, то когда уход атомных часов приближается к секунде, считают, что некий заранее заданный день длился на секунду дольше (то есть 86401 секунду), и эта секунда добавляется ровно в момент перехода к следующему дню. То есть после 59-й секунды отсчитывается 60-я секунда, и только потом нулевая секунда следующего дня. И если вы подумали, что я вас обманываю, то вот вам картинка
Дополнительная секунда, введённая 31 декабря 2016 года
Я буду называть эти дни високосными, по аналогии с високосным годом (надеюсь, я достаточно доходчиво объяснил, что это хоть и фундаментально похожие, но всё-таки разные понятия). Таким образом убивают двух зайцев: UTC тикают ровно со скоростью атомных часов, и при этом дни, подсчитанные по UTC, не убегают вперёд.
Нужно понимать, что если бы мы писали время как число секунд, прошедших с какой-то даты, у нас бы вообще не было никакой проблемы и никаких дополнительных секунд
- Простите, который сейчас час?
- 1 миллиард 704 миллиона 067 тысяч 200 секунд
Однако мы хотим в течение дня отсчитывать время именно как количество часов и минут и вот тут как раз и возникают сложности. В предположении, что день — это 86400 секунд, достаточно было поделить полное число прошедших секунд на 86400 и мы получали количество дней, которые потом переводили в дату. Но теперь нам нужно учитывать, что какие-то дни длились 86400 секунд, а какие-то 86401 секунду.
Григорианский календарь хорош тем, что даёт магическую формулу, которая заранее говорит, в феврале какого года появится дополнительный день. А вот с дополнительными секундами получилось сложнее. Для них не придумали никакой заранее заданной формулы: земля вращается неравномерно, иногда ускоряется, иногда замедляется. И да, допускается ситуация, когда какой-то день надо будет сделать короче на 1 секунду. Собирается международный комитет и на основании наблюдений за врашением Земли выносит решение: в этом году мы удлиним/укоротим такой-то день на одну секунду. Сейчас это случается раз в несколько лет.
Уверен, что вам вся эта ситуация не понравилась. Я думаю, что когда вы впервые в своей жизни узнали про григорианский календарь, он вам тоже вряд ли понравился. Ну правда, чтобы пересчитать дни в годы уже недостаточно просто сделать деление с остатком на 365, вместо этого приходится использовать более сложный алгоритм. Православная церковь так до сих пор живёт по юлианскому календарю, и у них сегодня 14 августа (холодновато правда для августа). Не удивительно, что у високосных секунд сразу образовалась партия противников. Против високосных секунд выступили конечно же механические часы, они к такому пердимоноклю были не готовы. Правда механические часы уходят от точного времени гораздо быстрее, чем 2 миллисекунды в год, поэтому их мнением можно, наверное, пренебречь. Выступили авторы устройств, которые не могут получать данные о изменениях времени из интернета. Опять же не очень понятно почему, ведь часто им время нужно лишь для координации собственных процессов, да и опять же, часы компьютера могут уходить на секунды в день и уж точно не должны страдать от этого. Самое интересное — это протест людей, которые синхронизируют время своих устройств через интернет. Чисто по человечески их можно понять: им нужно переписать алгоритмы пересчёта секунд в дату и отслеживать введение новых високосных секунд. Да что там хабр-писатели! Линюксовая программа date до сих пор не знает, что в 31-го декабря 2016-го года последняя минута имела длительность 61 секунду.
$ date -d"2016-12-31 23:59:60 UTC" +%s
date: invalid date ‘2016-12-31 23:59:60 UTC’
Яйцеголовые создатели ГЛОНАСС сели в лужу с написанием правильного кода (а ГЛОНАСС как раз использует UTC): их навигационная система не работала в течение суток в ночь с 30 июня на 1 июля 1997 года. А 1 января 2009 года сел в лужу национальный метрологический институт России (ВНИИФТРИ) (смешно, да?) со своими ntp-серверами. А инженеры меты Oleg Obleukhov и Ahmad Byagowi написали длинную статью о вреде этих високосных секунд, ведь они могут привести к движению в прошлое. Ну да, ну да… Мы все помним эпохальную статью о криворуких **ланах и печенье «Анёла». Всех этих людей понять можно, простить — нет.
Но если вы осознали всю мощь и величие дополнительных секунд, то вот вам загадка для друзей
Мы в далёком прекрасном прошлом. 31-е декабря 2016-го года. Мы встречаем новый год в Лондоне. Да, там, где рыба, чипсы, чай, дрянная еда, погода еще хуже, Мэри, етить её, Поппинс ©. Лондон! На часах 23:59:50. Мы подняли бокалы. Сколько времени осталось до наступления нового года?