Пользователь
0,0
рейтинг
20 октября 2014 в 12:20

Администрирование → Готовим 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 ftp.ru.debian.org/debian/pool/main/t/tzdata/tzdata_2014h-2_all.deb

dpkg -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 ftp.ru.debian.org/debian/pool/main/t/tzdata/tzdata-java_2014h-2_all.deb
dpkg -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.java
java tzcheck

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

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

Подробнее
Спецпроект

Самое читаемое Администрирование

Комментарии (31)

  • 0
    Ссылки проверяли?

    wget http://ftp.ru.debian.org/debian/pool/main/t/tzdata/tzdata_2014h-1_all.deb
    ОШИБКА 404: Not Found.
    • 0
      Спасибо, уже после публикации вышел 2014h-2. Я поправил ссылки.
  • +2
    Спасибо за жабу :-)

    А в Wheezy уже приехал штатный пакет.
  • 0
    Я бы добавил ещё одно замечание в статью:
    Существует много ПО использующего не системную, а собственную java машину. Обновление tzdata-java в системе на неё не повлияет.
    Проще всего:
    1. Вычислить какие java машины у Вас используются в системе. Например просмотреть список процессов java
      ps aux | grep java
      

      В выводе будет видно где установлена используемая java машина.
    2. Для каждой обнаруженной java машины в системе запустить
      <полный путь к обнаруженному java> -jar tzupdater.jar -u
      


    А то может быть сюрприз ;)
    Часто собственными java «страдают» вендоры всяческих бизнес приложений.
  • –4
    Хранишь время не в UTC — страдай! Давно уже известно.
    • 0
      При чём тут это?
      Время помимо хранения должно ещё:
      1. Отображаться пользователю
      2. Корректно преобразовываться в UTC из пользовательского ввода
      • 0
        Конкретно к посту это не имеет отношения, т.к. про хранение в ней ни слова.
        Это больше эмоциональное высказывание в честь очередной смены часового пояса.
  • +2
    Зачем проверять текущее время? Если оно неправильно сейчас, то сервер пора выбрасывать. Делал такую проверку правил перевода часов на своем SLES:

    STR=`/usr/sbin/zdump -v /etc/localtime|grep 2014`
    
    if [ -z "$STR" ];
        then
    	echo "Timezone is out of date. Need update."
        else
    	echo "Timezone is already updated, exiting."
        exit;
    fi
    


    Когда снова придется проверять нужно ли обновление, я поменяю одну очевидную циферку, а не две магических.
  • –1
    а с lenny неподскажите?
    • 0
      Для любой системы (если она, например не поддерживается) есть вариант обновить вручную
      Описанное в статье обновление tzdata явы через tzupdater.jar одинаково для всех систем.
    • +1
      Только что в lenny проделал:
      wget http://ftp.de.debian.org/debian/pool/main/t/tzdata/tzdata_2014h-0wheezy1_all.deb
      dpkg -i tzdata_2014h-0wheezy1_all.deb
      


      Все работает, скрипт автора выдает OK.
  • 0
    в lenny — собрать deb, особенно актуально, если много серверов
  • +1
    Не забываем обновить tz в MySQL habrahabr.ru/post/240937.
    На прошлом глобальном переводе часов поимели с этим проблем.
  • 0
    Хм. Что-то меня терзают смутные сомненья ©, что tzdata 2014h-2 все равно не работает. Может кто в курсе?
    Как проверялось:
    1. Ну банальное:
    dgeliko@pss:~$ date
    Пн окт 20 18:21:22 MSK 2014
    dgeliko@pss:~$ date -d 7days
    Пн окт 27 18:21:24 MSK 2014
    


    2. Переводилась принудительно дата на 26.11.2014 на 01:59:50 и выжидалось энное количествое времени. Дата не менялась, после 01:59:59 выводилось 02:00:00.
    Куда рыть?
    • 0
      Далеко перевели. Выставляйте 00:59:59 и ждите час или выставляйте время в UTC. Система считает, что время уже перевелось.
      • 0
        Пробовал в UTC — не работало тоже.
        • 0
          Ну тогда нужно сделать «zdump -v /etc/localtime | grep 2014» и убедиться, что таймзона верная. Если вывод будет, то вы что-то делаете не так. Если нет — неправильная таймзона.
          • 0
            И это все делал. Вообще странно ведет себя система при этом обновлении, в 2011 году проблем с проверкой было намного меньше, всё удалось проверить с пол пинка и все работало более предсказуемей.
            • 0
              У меня сработало, если устанавливать время в UTC, то есть date -u -s «25 oct 2014 21:59:55». Через 5 секунд получается Sun Oct 26 01:00:00 MSK 2014, как и должно быть. Если без ключа -u устанавливать, то получается 02:00:00.
              • 0
                У меня тоже сработало выставление в UTC, но только после ребута машины :-(
    • 0
      date -d 604800sec
      
    • 0
      26 октября, а не ноября.
      • +1
        Пардон, просто опечатка при наборе.
    • 0
      На 26.10 имеет смысл переводить. Октябрь 10 месяц.
      Прошу прощения, не заметил комментария ниже.
  • 0
    Пардон, если проверить со сдвигом по часам — все работает корректно.
  • 0
    Для debian 6 тоже зааплоадили, так что скоро появится в репах squeeze-lts
    • 0
      Прилетело в сквиз
  • 0
    А подскажите, плз, вот сейчас GMT-4, а будет вечный GMT-3 для Москвы?
    • 0
      Сейчас UTC+4, будет UTC+3.
      Насчет вечного: думаю, что до очередного указа =)
      • 0
        Ну как минимум «декретное» время не отменили, так что может ещё всё впереди…
        • –1
          Понятно, спасибо!
          Просто когда в 2011 году перевели, то я сделал в центосе вот так:

          1) vim /etc/sysconfig/clock
          
          ZONE="Etc/GMT-4"
          UTC=true
          ARC=false
          
          2) cp /usr/share/zoneinfo/Etc/GMT-4 /etc/localtime
          
          3) /etc/init.d/ntpd stop
          
          4) ntpdate ntp.ubuntu.com pool.ntp.org
          
          5) /etc/init.d/ntpd start
          
          6) /sbin/clock -w # Установка аппаратных часов
          
          


          И больше про время и перевод времени не вспоминал. Все корректно работало.
          Если теперь по аналогии хочу сделать и для предстоящего перевода.
          Получается все тоже самое только надо юзать GMT-3?

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.