Как на самом деле устроены часовые пояса
· 4 мин чтения
Часовой пояс — не полоса на глобусе, а именованный набор правил о том, что часы в определённом месте показывали, показывают и должны показывать. В этом различии и заключается весь предмет.
Спросите почти кого угодно, что такое часовой пояс, и вам опишут вертикальную полосу на карте: мир, поделённый на двадцать четыре равные доли по часу каждая, определяемые долготой. Эта картина аккуратна, легко запоминается и неверна ровно настолько, чтобы однажды стоить вам встречи.
Часовой пояс — это именованный набор правил, который ведёт государство, о том, что показывают часы на определённой территории. Правила могут меняться. Они меняются по политическим и экономическим причинам, иногда с предупреждением за две недели. Долгота — это то, с чего идея началась; это не то, чем она закончилась.
Откуда взялась идея
До 1880-х годов каждый город держал собственное время, выставленное по местному полудню — моменту, когда солнце пересекает меридиан над головой. Бристоль отставал от Лондона на десять минут, и никого это не смущало, потому что ничто не двигалось достаточно быстро, чтобы десять минут что-то значили.
Железные дороги это изменили. Расписание, где поезд отходит в 10:15, бесполезно, если 10:15 означает разное на двух концах линии, и уже к 1840-м британские железнодорожные компании попросту навязали всей своей сети лондонское время. США последовали в 1883 году: железные дороги собственной волей разрезали страну на четыре пояса. Международная меридианная конференция 1884 года сделала Гринвич нулевым меридианом и дала миру общую точку отсчёта.
Важное в этой истории то, что часовые пояса придумали для решения задачи согласования — и придумали их те организации, у которых эта задача была. Они никогда не описывали, где находится солнце.
Что на самом деле содержит пояс
Авторитетный источник — база данных часовых поясов IANA, известная также как tzdata или база Олсона. Это текстовый файл, обновляемый несколько раз в год, и всякая операционная система, всякий браузер и всякий язык программирования, которыми вы пользуетесь, читают какую-то её версию.
Для каждого пояса она хранит:
- идентификатор вида
America/New_YorkилиAsia/Kathmandu - смещение от UTC, действовавшее в каждый период истории этого пояса
- правила того, когда это смещение меняется, если оно меняется
- сокращение для каждого периода, если оно существует
Идентификаторы построены по схеме Регион/Место, и место — это представительный город, а не страна: страны делятся, объединяются и меняют свои правила независимо от границ. America/Argentina/Buenos_Aires существует потому, что провинции Аргентины когда-то держали разное время.
Обратите внимание, чем пояс не является: он не смещение. America/New_York — это не «UTC-5». Это пояс, чьё смещение часть года равно UTC-5, а остальное время UTC-4, который во Вторую мировую круглый год держался на UTC-5 и который до 1966 года работал по другому набору правил. Сохранить «UTC-5» и назвать это Нью-Йорком — самая распространённая ошибка с часовыми поясами в программах.
Правила меняются, и не постепенно
В 2016 году Турция отказалась от летнего времени примерно за три недели до перехода и осталась на UTC+3 навсегда. В 2018 году Северная Корея сдвинула часы на 30 минут, чтобы снова совпасть с Югом. В 2022 году Иран отменил летнее время; в том же году Мексика отказалась от него на большей части территории. Египет вернул его в 2023-м, отменив в 2014-м.
Каждый из этих случаев стал выпуском tzdata, и каждый сломал любую систему с жёстко зашитой таблицей смещений. Именно поэтому механизм, стоящий за каждой страницей этого сайта, читает смещения из копии tzdata в среде выполнения, а не из чего-либо сохранённого здесь. Новая сборка подхватывает новые правила; править ничего не нужно.
Почему смещения не всегда кратны часу
Примерно пятая часть населения мира живёт со смещением, не кратным целому часу от UTC. Индия — UTC+05:30, выбранный как единый компромиссный пояс для страны, достаточно широкой, чтобы оправдать два. Непал — UTC+05:45, и эти сорок пять минут отчасти утверждают независимость от индийского времени. Острова Чатем — UTC+12:45. Ньюфаундленд — UTC-03:30.
Программа, исходящая из того, что смещения кратны часу, не просто округляет: она выдаёт ответы, ошибающиеся на 30 или 45 минут для сотен миллионов людей. А это ровно тот размер ошибки, который замечают во время звонка, а не до него.
Два дня в году, когда местное время — не функция
Летнее время создаёт два ежегодных разрыва, и именно из-за них «перевести это местное время» сложнее, чем кажется.
Перевод вперёд стирает час. В Нью-Йорке в день перехода сразу за 01:59:59 следует 03:00:00. Местного времени 02:30 не наступает. Если пользователь его введёт, правильного момента для ответа не существует — есть только правила о том, что вернуть взамен.
Перевод назад повторяет час. 01:30 наступает дважды: один раз по летнему времени и ещё раз, часом позже, по стандартному. Одно только местное время действительно двусмысленно; нужно знать, какое из двух вхождений имелось в виду, а почти ни один интерфейс об этом не спрашивает.
Каждый инструмент на этом сайте разрешает оба случая явно и сообщает, что именно сделал. Молча выбрать одно из них — это тот путь, на котором запись в календаре оказывается на час не там, и никто не замечает этого до самого звонка.
Что из этого следует на практике
Из устройства вытекают три правила, и они покрывают почти всё, что идёт не так:
- Храните моменты, а не местное время. Метка времени в UTC однозначна. Местное время — это метка времени плюс пояс плюс правило для двух неудобных дней.
- Храните идентификатор пояса, а не смещение.
Europe/Londonпереживёт смену правил;UTC+0— нет, да и полгода он попросту неверен. - Переводите при выводе, используя tzdata среды выполнения. Не при сохранении и никогда — из таблицы, которую вы ведёте сами.
По той же причине этот сайт постоянно приписывает к смещениям «на момент последней сборки», а текущее время считает у вас в браузере. Эти правила не наши, чтобы их замораживать.