2014-10-24

О времени

Федеральный закон от 21.07.2014 N 248-ФЗ «О внесении изменений в Федеральный закон «Об исчислении времени» доставил много попоболи.

На час назад
Таймзоны у нас не просто поменялись, еще и добавились новые. Если посмотреть ченджлоги Time Zone Database, то выходит:
  • большинство часовых поясов передвигаются на час назад
  • Магаданская область (Asia/Magadan) и Забайкальский край передвигаются на два часа назад
  • Чукотка (Asia/Anadyr), Камчатка (Asia/Kamchatka), Кемерово (Asia/Novokuznetsk), Самара и Удмуртия (Europe/Samara) не переводят часы
  • Asia/Novokuznetsk переименовывается из NOVT в KRAT
  • из Asia/Yakutsk выделяется новая таймзона Asia/Chita (и переводится на два часа назад)
  • из Asia/Magadan выделяется новая таймзона Asia/Srednekolymsk (и переводится на один час назад)
Админам Читы и Республики Саха необходимо не только обновить пакеты, но и поменять таймзоны.

Да какая разница

С обновлениями все, кстати, плохо. Нужная версия tzdata (а именно 2014f или новее) появилась в Debian Wheezy лишь с неделю назад, а до Squeeze так еще и не докатилась (хоть вроде смержили 20 октября).
В Java все получше. Обновления доступны еще с августа. Вот только ни в один JDK, даже самый распоследний, они не входят. Так что нужно самостоятельно скачать TZUpdater и выполнить его с правами администратора в вашей Java системе.
В Windows своя отдельная боль. Таймзон там сильно меньше, чем в стандартной Time Zone Database, а значит менять зону руками придется почти всем.
Вот что произойдет этой ночью (там где будет перевод на один час):
Показания часовВремя
00:00 - 00:59старое летнее время
01:00 - 01:59старое летнее время
01:00 - 01:59новое зимнее время
02:00 - 02:59новое зимнее время
Показания часов между часом и двумя ночи будут повторены дважды, но с разным смещением относительно UTC.
Отсюда следуют интересные выводы по поводу хранения времени (во всяких ваших БД). Которые касаются любых переходов между зимним и летним временем. Просто, за последние три года (последний раз мы переходили на летнее время весной 2011) все как-то расслабились и породили системы, которые работают со временем неправильно.
Неправильно хранить и передавать часы-минуты-секунды в локальном часовом поясе без указания явного смещения относительно UTC. Ибо локальное смещение, как мы видим, дело непостоянное и у вас либо час пропадет, либо будут неоднозначности. Как в данном случае, когда между часом и двумя ночи будет дважды. Впрочем, тесты показывают, что неоднозначности разрешаются в пользу нового зимнего времени. И этот способ, блин, используется сильно чаще, чем следует.
Правильно хранить и передавать часы-минуты-секунды с явным указанием текущего смещения относительно UTC. В этом случае неоднозначности не возникает и все ок. Именно такой формат подразумевается стандартом ISO 8601, что-то вроде YYYY-MM-DDThh:mm:ss±hh.
Правильно хранить и передавать часы-минуты-секунды в UTC с явным подразумеванием, что это UTC. UTC не переходит на летнее время, и пока не будет переходить — все ок. Именно такой формат подразумевается ISO 8601 с Z суффиксом: YYYY-MM-DDThh:mm:ssZ.
Правильно хранить и передавать часы-минуты-секунды в виде Unix Timestamp, т.е. числа секунд (или миллисекунд), прошедших с 1 января 1970 года UTC. Таймстамп — это вполне себе глобальный и надежный счетчик времени. Тут лишь есть небольшая проблема с представлением дат ранее 20 века и позднее 2038 года. Однако с повсеместным переходом на 64битные ОС это уже не актуально.
P.S. Надеюсь, я не сильно опоздал с этим постом :)

UPD: В мобильном мире все тоже плохо. Я полагаю, что 90% устройств вообще никогда не получат нужные обновления таймзон. В исходниках Android свежий tzdata имеется только в Android L Preview. Впрочем, для Android есть рутованная таблетка. Не пробовал, но не вижу причин, почему не будет работать.
Дали