Ручное обновление базы данных часовых поясов в старых дистрибутивах Линукс

Все может быть, что данная заметка пригодится тем суркам-администраторам, которые до сих пор (о, ужас!) не перевели системные часы своих серверов, позволив умным машинам установить зимнее время. Да, конечно, мы-то с Вами к таким не относимся и вовремя пропатчили свою любимую ОС, под которой крутится успешно не один сайт.

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

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

Ручное обновление приводится на примере дистрибутива Линукс Fedora 8 (думаю, пример будет также применим и к дистрибутивам Red Hat и CentOS). Именно под этой системой трудится веб-сервер на одной из машин, за которой я присматриваю.

Итак, логинимся под обыкновенным пользователем по SSH и смотрим текущее время (оно берется из файла /etc/localtime) и, сразу же, текущий установленный часовой пояс:

[user@server ~]$ date
Fri Nov 18 18:59:57 MSK 2011
[user@server ~]$ cat /etc/sysconfig/clock | grep ZONE
ZONE="Europe/Moscow"

Здесь мы машинально смотрим на свои «соломенные», видим отставание на один час и тут же проверяем был ли осуществлен переход на зимнее время наверняка:

[user@server ~]$ zdump -v /etc/localtime | grep 2011
Europe/Moscow  Sat Mar 26 22:59:59 2011 UTC = Sun Mar 27 01:59:59 2011 MSK isdst=0 gmtoff=10800
Europe/Moscow  Sat Mar 26 23:00:00 2011 UTC = Sun Mar 27 03:00:00 2011 MSD isdst=1 gmtoff=14400
Europe/Moscow  Sat Oct 29 22:59:59 2011 UTC = Sun Oct 30 02:59:59 2011 MSD isdst=1 gmtoff=14400
Europe/Moscow  Sat Oct 29 23:00:00 2011 UTC = Sun Oct 30 02:00:00 2011 MSK isdst=0 gmtoff=10800

Строки с октябрьской датой подтверждают факт ненужного теперь перевода на зимнее время (подробный пост про это сделал хабрапользователь GreyCat).

Чтобы поправить ситуацию идем на сайт IANA (The Internet Assigned Numbers Authority) — именно там теперь публикуются обновленные файлы The Time Zone Database (базы данных временных поясов известную также среди сисадминов как tz database или zoneinfo database) и скачиваем файл tzdata, содержащего последние обновления. Для скачивания удобней воспользоваться утилитами наподобие wget или curl (что найдется под рукой), а не браузером:

[user@server ~]$ wget http://www.iana.org/time-zones/repository/releases/tzdata2011n.tar.gz
или
[user@server ~]$ curl -O www.iana.org/time-zones/repository/releases/tzdata2011n.tar.gz

Тут же распакуем содержимое скачанного файла tzdata (можно в тот же каталог, куда скачали):

[user@server ~]$ tar xzf tzdata2011n.tar.gz

И, наконец, самое главное.
Компилируем файл временных поясов europe в бинарный вид и тут же делаем ключевой файл /etc/localtime символической ссылкой на соответствующий поясу файл (в данном случае пояс Europe/Moscow), иначе система не узнает о том, что мы обновили содержимое базы.

Данная команда потребует прав суперпользователя, поэтому исполнять ее нужно от имени root:

[root@server user]$ zic europe
[root@server user]$ ln -sf --suffix=.backup /usr/share/zoneinfo/Europe/Moscow /etc/localtime

На этом — всё! Смотрим время, теперь выводится все правильно:

[root@server user]$ date
Fri Nov 18 20:14:37 MSK 2011

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 34

    +5
    А можно поправить файл /etc/sysconfig/clock и привести к такому виду:
    ZONE=«Etc/GMT-4»
    UTC=true
    ARC=false,
    и затем просто заменить симлинку таким макаром: ln -s /usr/share/zoneinfo/Etc/GMT-4 /etc/localtime
    А еще часто нужно обновить таймзону для джавы, которая использует свою информацию о таймзонах, а не системную. Для этого надо скачать tzupdater с сайта оракла и выполнить /путь/к/бинарнику/джавы/java -jar tzupdater.jar и перезапустить джаву.
      0
      Забыл добавить. Просмотреть дату через определенное время (для проверки, переведутся ли часы после наступления часа X) можно командой date -d '180days', где 180 — количество дней, через которое должны перевестись часы.
        0
        Ваш способ не подходит в случае, когда требуется проверить, какой оффсет был в определенный момент в прошлом — будет всегда возвращаться одна и таже таймзона.
          0
          # date -d '-30days'
          Пнд Окт 24 15:00:07 MSK 2011
          не? Или я не правильно понял вашу реплику?
            0
            Попробуйте -1year.
              0
              Ага, понял. Ну логично, таймзона же изменилась, для того чтоб знать что было в прошлом — надо ее и привести к прошлому виду =)
                0
                Если запросы к системе идут чаще 1 раза в неделю, достаточно накладно менять таймзону каждый раз. Как решение, надо использовать не POSIX формат, а формат Олсона, тогда все должно быть ОК.
                  0
                  Пардон, на вскидку не могу придумать зачем может понадобится смотреть время в прошлые года/месяцы. По идее все операции (и таймстэмп в том числе) обычно заносятся в БД (в проектах). Для чего может понадобится смотреть какое время было год назад например? Да еще и несколько раз в неделю.
                    0
                    Вы абсолютно правы, это не обычная ситуация. Проблема в том, что таймстемп в базе может быть и без таймзоны и лучше иметь защиту от такой ситуации.
                      0
                      Лучше при проектировании проекта сразу делать все нормально, чем потом придумывать костыли =)
                        +1
                        Не всегда можно все учесть.
        +1
        Теперь и у меня появилась карма поставить плюс вашим комментариям :)
        Они самые дельные в этом топике.
        +2
        А типа «суркам-администраторам» не комильфо просто поставить через yum пакет от нового релиза, надо непременно вот такое вот делать, да? Либо указать релиз/арх и апдейтить, либо скачать просто rpm, либо как-то вот так:
        yum --nogpgcheck install mirror.yandex.ru/fedora/linux/updates/16/i386/tzdata-2011n-2.fc16.noarch.rpm
        , либо ещё куча способов, все короче, проще и точно не хуже.
          0
          Не то что «не комильфо», а скорее религия не позволяет ставить пакет от совершенно другого релиза. Это не 100%-ый и просто не красивый способ, IMHO конечно.

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

          Поэтому заметку можно было бы начать фразой из комментария ниже:
          Иногда пакет от нового релиза не встает, либо релиз уже давно не поддерживается.

          Но уверен, что есть и другие способы — более короткие и простые.
            0
            По опыту на 3й рхел становится и работает рпм-ка собранная в 5м центосе.
          +1
          Иногда пакет от нового релиза не встает, либо релиз уже давно не поддерживается.
          P.S.
          # uname -a
          Linux payment 2.4.18-3bigmem #1 SMP Thu Apr 18 07:17:10 EDT 2002 i686 unknown
          # cat /etc/redhat-release
          Red Hat Linux release 7.3 (Valhalla)
            0
            Это мне? Понятное дело, что восьмая федора давно не поддерживается. Но я специально указал, что надо явно указать новый релиз. Ну вот пусть от 16-го, я даже ссылку привёл на пакет в репозитории. Этот пакет от нового релиза встанет 100%, можно и не сомневаться. Да там вставать особо нечему, хоть зависимости и обширные.
              0
              Да, вам, просто промахнулся с ответом =).Ну возможно на относительно недавние релизы и встанут пакеты, а вот на мой Red Hat 7.3 думаю пакет поставить будет проблематично.
            0
            вместо
            ln -sf --suffix=.backup /usr/share/zoneinfo/Europe/Moscow /etc/localtime
            можно просто
            zic -l Europe/Moscow
              +1
              Несомненно можно. Только у вас не останется предыдуще версии /etc/localtime
              А с моим «страшным» вариантом останется /etc/localtime.backup, на всякий случай.
              0
              На этом — всё! Смотрим время, теперь выводится все правильно

              Ещё не всё. Необходимо перегрузить некоторые сервисы.
                0
                Имелось ввиду «всё» касательно системного времени;)
                Некоторые сервисы требуют перезагрузки, вы — правы.

                В моем конкретном случае потребовалось перезагрузить Cron и MySQL.
                Python, Ruby, Php и некоторые другие «видят» верное системное время без перезагрузки.

                PS: Еще, если не ошибаюсь, в Java своя база временных поясов.
                  0
                  У php тоже своя база. И если вдруг на сервере крутится 5.2.х, который нельзя апдейтить до 5.3.х по каким-либо соображениям, то придется еще и к php прикручивать timezonedb из pecl'a. Впрочем, там ничего сложного нет.
                +1
                Я для этой цели просто подменил файлик /usr/share/zoneinfo/Europe/Moscow на свежую версию из другого дистрибутива.
                И проблема оказалась решена.
                  0
                  Не забываем, что у некоторых пакетов (например PHP) собственная база часовых поясов. И обновить нужно и все такие пакеты.
                    0
                    pecl install timezonedb
                    Под генту может выдать libtool: Version mismatch error. This is libtool 2.2.6b, but the definition of this LT_INIT comes from an older release и тут начинаются танцы с бубном.
                    решается
                    emerge --sync
                    emerge pecl-timezonedb
                    вот только эта зараза и весь PHP обновить хочет и попутно еще пару пакетов пересобрать.
                      0
                      Да, вы правы. Но насчет PHP все интересно: выдается правильное время, несмотря на то, что PHP не обновлялся и timezonedb не ставился.

                      Видимо функции, которые используются в скриптах для работы со временем:
                      gettimeofday();
                      time();
                      getdate();
                      localtime();
                      
                      используют данные системных вызовов :)
                      0
                      О сколько нам открытий чудных готовит смена поясов (часовых). И это в купе с отменой перевода стрелок часов на летнее время.
                        +1
                        Советую привести вариант с curl вместо wget. На динозаврах и палеозаврах curl намного чаще есть сразу в системе чем wget, который еще и надо будет тогда поставить.
                          0
                          Ок, подскажите как правильно, я добавлю.
                          Вот так?

                          curl -s http://www.iana.org/time-zones/repository/releases/tzdata2011n.tar.gz --remote-name


                          Просто я совсем не использую curl.
                        0
                        Внес в текст статьи вариант с curl.
                          0
                          добавьте в статью что последний доступный релиз можно посмотреть на странице
                          www.iana.org/time-zones

                        Only users with full accounts can post comments. Log in, please.