[Из песочницы] Готовим Debian к переводу часов 26 октября 2014 года

Приближается 26 октября 2014 года — день, когда в 2 часа ночи в большинстве регионов России в очередной (и как снова обещано в последний) раз часы буду переведены на час назад. Кроме того, в некоторых регионах происходит смена часового пояса. Ознакомиться подробно где и что меняется можно в Федеральном законе от 21.07.2014 № 248-ФЗ «О внесении изменений в Федеральный закон «Об исчислении времени».В этом посте я хочу акцентироваться на вопросе приведения в актуальное состояние данных о часовых поясах в Debian.Debian для хранения информации обо всех часовых поясах, существующих в мире, использует базу timezone database (короткое название tzdata). Эта база содержит полные данные обо всех изменениях часовых поясов, которые происходили в мире по тем или иным причинам, что позволяет вести точные расчеты локального времени на любой момент, начиная с 1 января 1970 года. В частности, актуальная версия tzdata позволяет получить точное локальное время как в период времени до вступления в силу Федерального закона №248-ФЗ, так и после (начиная с 2 часов ночи 26 октября 2014 года). В Debian база tzdata распространяется в виде одноименного пакета.

Изменения, которые вносит Федеральный закон №248-ФЗ, отражены в базе tzdata, начиная с версии 2014f. По состоянию на 18 октября 2014 года в официальных репозиториях Debian для Wheezy (stable) и Squeeze (oldstable) пакет tzdata имеет более раннюю версию 2014e, в которой еще не предусмотрен перевод часов в России 26 октября 2014 года. В то же время для Jessi (testing) (Update1: с 19.10.2014 и для Wheezy (Stable) уже выложена актуальная версия 2014h. Таким образом, в Wheezy и Squueze для корректного исчисления времени после 26 октября потребуется установить пакет своими силами. Сделать это просто:

wget http://ftp.ru.debian.org/debian/pool/main/t/tzdata/tzdata_2014h-2_all.debdpkg -i tzdata_2014h-2_all.deb

После этого в системе будет установлена обновленная версия tzdata, однако для того, чтобы её начали использовать уже запущенные в системе сервисы (в частности syslog), потребуется выполнить их перезапуск.

Приведу также пример простого скрипта, который позволит проверить, что в вашей системе используется правильная база часовых поясов. Скрипт tzdata.sh выполняет проверку для Московского часового пояса:

tzcheck.sh:

#!/bin/sh T1=$(LC_ALL=C TZ=Europe/Moscow date -d @1409067890) if [ »$T1» != 'Tue Aug 26 19:44:50 MSK 2014' ] ; then echo FAIL! Wrong TZ BEFORE 26 Oct 2014! exit 1 fi T2=$(LC_ALL=C TZ=Europe/Moscow date -d @1416667890) if [ »$T2» != 'Sat Nov 22 17:51:30 MSK 2014' ] ; then echo FAIL! Wrong TZ AFTER 26 Oct 2014! exit 2 fi echo OK Если всё в порядке, будет выведена надпись OK.

Если у вас в системе установлена Java, то одним обновлением пакета tzdata обойтись не получится. И OpenJDK, и Sun/Oracle Java используют свои, отдельные от общесистемных, базы данных часовых поясов. Их тоже потребуется обновить.

В случае OpenJDK база представляет собой пакет tzdata-java, имеющий те же номера версий, что и пакет tzdata. Обновить его просто по аналогии:

wget http://ftp.ru.debian.org/debian/pool/main/t/tzdata/tzdata-java_2014h-2_all.debdpkg -i tzdata-java_2014h-2_all.deb

В случае с Java от Sun/Oracle потребуется воспользоваться специальной утилитой Java Time Zone Updater Tool, скачав её с сайта Oracle. Для обновления базы часовых поясов потребуется запустить её с ключом -u

java -jar tzupdater.jar -u

Обратите внимание, что если вы когда либо ранее скачивали данную утилиту, то воспользоваться этой старой версией нельзя — она ничего не обновит. С каждым обновлением базы часовых поясов Oracle выпускает новую версию этой утилиты, для получения самой актуальной базы нужно пользоваться текущей версией.

Как и в случае с обычными сервисами, уже запущенные Java-приложения могут потребовать перезапуска для того, чтобы они начали пользоваться обновленной версией базы часовых поясов.

Ниже привожу пример кода на Java, который позволит проверить для Московского часового пояса, что с исчислением времени в Java у вас всё хорошо:

tzcheck.java:

import java.util.*; import java.text.DateFormat;

public class tzcheck { public static void main (String[] args) { Calendar cal = Calendar.getInstance (TimeZone.getTimeZone («Europe/Moscow»)); DateFormat df = DateFormat.getDateTimeInstance (DateFormat.FULL, DateFormat.FULL, Locale.US); df.setCalendar (cal);

cal.setTimeInMillis (1409067890L * 1000L); if (! df.format (cal.getTime ()).equals («Tuesday, August 26, 2014 7:44:50 PM MSK»)) { System.out.println («FAIL! Wrong TZ BEFORE 26 Oct 2014!»); System.exit (1); }

cal.setTimeInMillis (1416667890L * 1000L); if (! df.format (cal.getTime ()).equals («Saturday, November 22, 2014 5:51:30 PM MSK»)) { System.out.println («FAIL! Wrong TZ AFTER 26 Oct 2014!»); System.exit (2); }

System.out.println («OK»); System.exit (0); } } Компилируем и запускаем: javac tzcheck.javajava tzcheck

Если всё в порядке, будет выведена надпись OK.

Update1: На выходных пока пост был на модерации для Wheezy выпустили штатный пакет с актуальной tzdata + вышла версия 2014h-2, ссылки в тексте поменял.

© Habrahabr.ru