Время Unix и запись ISO 8601
Внесистемная единица · величина: момент времени как целое число секунд от 1970 года
Девятнадцатого января 2038 года в три часа четырнадцать минут и семь секунд по всемирному времени тридцатидвухразрядный счётчик секунд дойдёт до 2 147 483 647 — наибольшего числа, какое он способен вместить. Следующий такт поднимет старший бит, и то же самое двоичное слово прочтётся уже как отрицательное: часы, которые хранят время именно этим счётом, окажутся не в 2038 году, а в декабре 1901-го. Курьёзом далёкого будущего это не назовёшь — промышленный контроллер или счётчик воды служит дольше, чем те двенадцать лет, что остались до срока.
Устроен этот счёт крайне просто: секунды идут подряд от полуночи первого января 1970 года, а сутки в нём всегда содержат ровно 86 400 секунд. Простота и есть источник обеих его особенностей. С одной стороны, из числа мгновенно получается календарная дата и обратно, так что всякий журнал событий, всякая база данных и всякая файловая система считают время именно им. С другой — високосную секунду в таком счёте выразить нечем, а значит, вопреки названию, он нумерует не секунды, а сутки с долями, и по-настоящему является линейной функцией от записи UTC, а не счётчиком прошедшего времени.
01 · Определение
Время Unix — число секунд, прошедших от полуночи первого января 1970 года по всемирному координированному времени, при условии, что в каждых сутках ровно 86 400 секунд. Запись ISO 8601 задаёт то же самое иначе: календарной датой, временем и указанием смещения от нулевого меридиана, причём порядок полей строго от крупного к мелкому.
Оговорка про 86 400 секунд — не мелочь, а самое существенное в определении. Високосную секунду, объявляемую службой вращения Земли, счёт вместить не может, и потому в момент вставки система либо повторяет одно и то же значение дважды, либо переставляет часы назад. Из этого следует важное: разность двух чисел unix не равна числу секунд, действительно прошедших между двумя событиями, если между ними была вставка, — расхождение с атомной шкалой набежало уже до двадцати семи секунд.
Предел же зависит не от определения, а от разрядности хранения. Тридцать два бита со знаком дают наибольшее значение 2 147 483 647, что приходится на девятнадцатое января 2038 года, а следующее приращение переводит старший бит в единицу и превращает число в отрицательное, отбрасывая часы в тринадцатое декабря 1901 года. Шестьдесят четыре бита отодвигают границу на двести девяносто два миллиарда лет вперёд, но целочисленные наносекунды в тех же шестидесяти четырёх битах кончаются уже в 2262 году.
Запись по стандарту решает другую задачу — не хранение, а обмен, — и потому в ней важны вещи, которых у числа нет вовсе: часовое смещение, разделитель между датой и временем и правило, что при равной длине строки лексикографический порядок совпадает с хронологическим. Последнее свойство и сделало формат основой сортировки в файловых именах и в журналах.
Ведите время ползунком и смотрите, как заполняется регистр: биты загораются справа налево, и пока старший, знаковый, остаётся тёмным, число положительно, а дата растёт. Стоит счётчику перешагнуть 2 147 483 647 — старший бит вспыхивает красным, всё число становится отрицательным, и часы прыгают в 1901 год.
Зелёная прямая — атомная шкала, где каждая секунда действительно секунда. Красная ступенчатая — время Unix, у которого при всякой вставке одна и та же метка выдаётся дважды, отчего линия замирает на месте. Расхождение уже составляет двадцать семь секунд и растёт, а потому счёт годится для календарной даты, но не для измерения длительностей в физике.
02 · Пересчёт
Введите метку или дату
Между всеми кратностями счёта — секундами, миллисекундами, микро- и наносекундами — переводы точны, поскольку различаются они только множителем. Приблизительна одна строка: перевод в атомную шкалу требует знать число вставок, накопленных к заданному моменту.
Разбор строки по стандарту лист делает в расширенной записи с буквой Z; базовая форма без разделителей вынесена в тонкие настройки.
Проблема 2038 года лежит не в стандарте, а в железе и в старом коде: тридцатидвухразрядные метки сидят в прошивках счётчиков, в промышленных контроллерах, в форматах файловых систем и в базах данных, где поле уже объявлено четырьмя байтами. Заменить тип в исходниках несложно, а вот перебрать миллионы установленных устройств за оставшиеся двенадцать лет — задача того же рода, что стояла перед двухтысячным годом.
| Значение | Пояснение | ||
|---|---|---|---|
| {u} | {name} | {value} | {note} |
03 · Порядки величин
логарифмическая шкала: от секунды до предела шестидесяти четырёх бит04 · Приборы измерения
Чем ставят метку на событие
Отдельная микросхема с батарейкой, которая ведёт счёт, пока устройство выключено. Хранит она обычно не метку Unix, а поля календаря по отдельности, и разрядность года у неё своя, так что в старых платах разговор о 2038 годе начинается уже с вопроса, до какого года считает сам чип.
Протокол NTP приводит часы машины к общему времени с точностью до единиц миллисекунд, и он же предупреждает о вставке особым флагом за сутки. Своя граница у него тоже есть, и наступает она раньше: счёт ведётся от 1900 года в беззнаковых тридцати двух битах и переполнится в феврале 2036-го.
В журнал метку пишут либо числом, либо строкой по стандарту, и второе предпочтительнее ровно по одной причине: у строк одинаковой длины алфавитный порядок совпадает с хронологическим, так что записи сортируются без разбора даты. Именно поэтому формат разошёлся далеко за пределы вычислительной техники.
Проверить готовность прибора к 2038 году можно единственным способом — перевести на нём часы за роковую границу и посмотреть, что станет с журналами, сертификатами и расчётом интервалов. Так уже нашли отказы в биллинге, в системах контроля доступа и в сроках действия ключей, где дата в будущем считается сложением и переполняется задолго до самой границы.
05 · Правила записи
От крупного к мелкому и всегда со смещением
Стандарт требует убывающего порядка полей, четырёх цифр года, дефиса как разделителя даты и буквы T перед временем; часовое смещение указывают либо буквой Z для нулевого меридиана, либо в виде плюс-минус часов и минут. Метку Unix пишут целым числом без разделителей разрядов и обязательно уточняют кратность, поскольку тысячная доля отличает секунды от миллисекунд, а по величине числа их легко спутать.
Первая запись читается по-разному в разных странах и потому в обмене данными недопустима. Вторая опускает и разделитель, и смещение, так что момент оказывается неопределён на сутки в обе стороны. Третья теряет ведущие нули, из-за чего строки перестают сортироваться алфавитно, а именно за это свойство формат и ценят. Четвёртая приравнивает счёт Unix к атомной шкале, тогда как между ними лежат двадцать семь секунд накопленных вставок.
06 · Соседние единицы
Рядом стоят все счёты, устроенные по тому же принципу, но от иного начала: время NTP от 1900 года, юлианская дата от полудня 4713 года до нашей эры, шкала спутниковой системы от января 1980-го. Различаются они только эпохой да единицей, а потому переводятся вычитанием постоянной.
секунды со знаком
предел уже в 2036-м
вставки учтены честно
Из паспортов Simetrium рядом стоят юлианская дата, откуда взята постоянная перевода, шкалы UTC, TAI и UT1, объясняющие пропавшие вставки, секунда как единица счёта и бит, чья разрядность и определяет предел.
07 · Исторический раздел
Эпоха, выбранная от нехватки битов
В первом руководстве по Unix время считалось шестидесятыми долями секунды от начала 1971 года, и в тридцати двух битах такой счёт умещал всего два с половиной года. Кончались они настолько быстро, что эпоху пришлось бы переставлять при каждом выпуске системы, и от долей секунды отказались в пользу целых.
Перейдя к целым секундам, разработчики получили запас в сто тридцать шесть лет и смогли выбрать начало по удобству, а не по нужде. Взяли первое января 1970 года — ближайшую круглую дату в прошлом, до которой машинные записи всё равно не доходили, — и с тех пор её не меняли ни разу, хотя система переписывалась целиком не однажды.
Международная организация по стандартизации свела расходящиеся национальные форматы в один и положила в его основу простое правило: поля идут от крупного к мелкому, все с ведущими нулями. Побочное следствие оказалось важнее замысла — такие строки сортируются как числа, и формат разошёлся в имена файлов, журналы и протоколы обмена.
Настольные и серверные системы перешли на шестьдесят четыре бита давно, и там граница отодвинута за всякий разумный горизонт. Опасность осталась в другом: в прошивках приборов с двадцатилетним сроком службы, в форматах файлов, где поле объявлено четырьмя байтами, и в расчётах будущих сроков, которые переполняются уже сегодня, стоит прибавить к нынешней дате пятнадцать лет.
Счёт, который вопреки названию не считает секунды
Определение времени Unix звучит как счёт секунд, однако требование ровных 86 400 секунд в сутках делает его чем-то иным: это линейная функция от записи UTC, а не мера прошедшего времени. Всякий раз, когда служба вращения Земли объявляет вставку, счёт обязан повторить одно и то же значение дважды либо перескочить назад, и разность двух меток теряет ту самую секунду. За полвека таких потерь набралось двадцать семь, а потому в задачах, где нужна настоящая длительность, берут атомную шкалу, а не эту.
Вторая особенность лежит вовсе не в определении, а в способе хранения, и это делает её единственным пределом в нашем каталоге, который назначен не природой и не соглашением, а разрядностью машинного слова. Юлианская дата не кончается никогда, потому что она число; время Unix кончается девятнадцатого января 2038 года, потому что оно поле в четыре байта. Разница между величиной и её представлением обычно занимает метрологов мало, а здесь именно она и определяет всё.
Каталог · единицы измерения
Паспорт на каждую величину
Семь базовых единиц СИ, двадцать две производные с собственными именами и внесистемные величины, без которых не обходится ни наука, ни быт. Каждая — отдельный лист: определение, пересчёт, приборы, правила записи, история. На 36 языках.