dimhold.by
← Статьи

344 скачка часов за этот год, два из них на целые сутки

Когда мне нужно завтра, я прибавляю 24 часа. Все знают, что это ломается дважды в год, все произносят слово “часовой пояс” на ревью, а потом правка уезжает в ветку вместе с этими 24 часами, потому что лечится оно библиотекой, которую сегодня никто не хочет тащить. Примерно так у меня и вышло в марте. Чего я не делал ни разу, так это не смотрел, что база говорит про содержимое года.

Поэтому прочитал её целиком. Каждую зону, которую знает рантайм, смещение на каждый день 2011 года. Каждое изменение уточнено до минуты двоичным поиском внутри суток. Получилось 418 зон, из них двигались хотя бы раз 185, всего 344 скачка.

336 скачков из этих 344 это тот самый час, вокруг которого весь спор. Интересны остальные 8.

размер скачка сколько кто 30 мин 2 остров Лорд-Хау, туда и обратно 60 мин 336 обычные 120 мин 3 Тролль дважды, Дэвис один раз 180 мин 1 Кейси, 27 октября 1440 мин 2 Апиа и Факаофо, 30 декабря прочитано 418 зон, двигались 185
Полоса на 60 минутах обрезана, чтобы влезть: там 336 против 2. Всё, подо что кто-либо когда-либо писал вспомогательную функцию, лежит в этой одной строке. Остальные 4 строки это то, на чём такая функция ошибается.

Остров Лорд-Хау двигается на полчаса. Это единственная такая зона в базе. Антарктические станции двигаются на 2 часа, Тролль дважды, Дэвис один раз. Кейси двигается на 3. Это 6 скачков, которых набор тестов из одних часовых случаев не увидит никогда.

Дальше идёт 30 декабря, которого ещё не было. До него 9 дней.

Сутки, которых не будет

В 10 утра по UTC в этот день Апиа уходит с минус 600 минут на плюс 840. Через час то же делает Факаофо. Обе перешагивают линию перемены даты, поэтому местный календарь идёт с четверга 29 декабря сразу на субботу 31 декабря. Для того, кто стоит там, пятницы не случится.

Любое расписание, которое отсчитывает сутки прибавлением 86400000 миллисекунд, выдаст в этих зонах пятницу. Любой отчёт с группировкой по местной дате получит пустую корзину в середине. Любая разница двух моментов, посчитанная в сутках, окажется на 1 больше.

Проверить это сегодня мне нечем. Никому нечем. Правило лежит в базе с проставленной датой. Это и есть всё предупреждение, которое кто-либо получит.

Весной вперёд, осенью назад, 26 исключений

Число, из-за которого я заподозрил собственный скрипт: 186 скачков идут вперёд и только 158 назад. Время положено возвращать к концу года, поэтому разница в 28 выглядела как ошибка в том, как я обхожу границу года.

Ошибки нет. 30 зон заканчивают 2011 год на смещении, отличном от того, с которого начали.

зоны, у которых смещение 31 декабря не равно смещению 1 января 25 зон, +60 Россия и Беларусь: ушли в марте, остались 1 зона, +60 Баия: летнее время идёт 2 зоны, +1440 Апиа, Факаофо 1 зона, +180 Кейси 1 зона, -120 Дэвис 186 скачков вперёд против 158 назад: вот куда ушли 28
Симметрия, которую все подразумевают, не является свойством года. В 2011 она нарушена 30 раз. 25 из них это одно решение, принятое в одной стране в марте.

25 зон из 30 это Россия и Беларусь, которые ушли на летнее время в марте и там остались. Минск в этом списке. Это как раз та часть, которой я не знал, пока её не напечатал скрипт. Весь год я смотрел на эти часы на стене. Двадцать шестая зона с плюс 60 это Баия в Бразилии, у которой просто середина лета, когда год заканчивается.

Что коду приходится переживать

186 скачков вперёд означают 186 отрезков местного времени, которых в 2011 году не существует. Спроси 02:30 не в ту ночь не в той зоне: такого момента нет. 158 скачков назад означают 158 отрезков, которые случаются дважды, поэтому местная отметка времени без смещения двусмысленна на час. На Лорд-Хау она двусмысленна на полчаса.

И сами смещения не те круглые числа, которые обычно подразумевает схема данных. За год база использует 41 разное смещение от UTC. Из них 15 не кратны часу: привычные половины плюс 5.75, 8.75, 12.75 и 13.75.

Чего я не проверял

Говорит ли база, которую я читаю сегодня, правду про январь. Данные зон правят задним числом, поэтому файл, описывающий 2011 год, это файл, который правили в течение 2011 года. Мой обход не отличит правило от его позднейшей поправки. Ещё я прочитал только то, что поставляется с рантаймом, то есть одну копию базы вместо нескольких, которые обычно живут в системе. Значит операционная система, язык и движок базы данных могут отвечать каждый со своей давности. Это то расхождение, на которое я уже напарывался. Здесь оно не измерено.

Узкое утверждение это правило о том, чего не предполагать. Сутки это не 24 часа, смещение это не целое число часов, часы не возвращаются к концу года. А через 9 дней пятница пропадёт у двух зон, у которых есть все основания рассчитывать на пятницу.