- PVSM.RU - https://www.pvsm.ru -
Многие уже поставили обновление tzdata на свои любимые дистрибутивы и с нетерпением ждут конца света 26 октября 2014 года, когда можно будет в 2 часа ночи ощутить себя на все 3.
Но всё ли в порядке, если вы пишите на PHP и используете Symfony Forms, или просто php-intl?!
Мой ответ — нет.
Проверить себя вы можете просто:
<?php
$dateIn = '27.10.2014';
$tz = 'Europe/Moscow';
date_default_timezone_set($tz);
$intlDateFormatter = new IntlDateFormatter('ru_RU', 2, -1, $tz, 1, 'dd.MM.yyyy');
$timestamp = $intlDateFormatter->parse($dateIn);
var_dump($intlDateFormatter->format($timestamp));
var_dump(date('d.m.Y', $timestamp));
На debian wheezy, centos после обновления tzdata этот код выведет:
string(16) "27.10.2014"
string(16) "26.10.2014"
Это происходит потому, что у библиотеки icu своя база данных временных зон (это популярное занятие, например, также делает php, java, chrome и вагон другого софта) и при пересчете даты в unixtimestamp она отнимает 4 часа, а php функция date прибавляет только 3, и если поле у вас только для ввода даты, то после отбрасывания времени вы получите на день меньше от введенной даты.
Ситуацию усугубляет еще и то, что данные эти хранятся в виде библиотеки libicudata, поэтому готовьтесь собирать icu из исходников.
Все действия далее выполняются на отдельной VM под управлением CentOS 6.5 + remi + libicu-last.
По версии пакета определяем версию icu — 50.1.2 (исходники на сайте icu [1]), также отсюда [2] скачиваем все *.res файлы, где (в ссылке)
2014i — версия tzdata;
44 — версия libicu (44 и все что больше);
le — little endian (дада если у вас mips arm и т.п. вам может потребоваться другой набор ресурсов).
tar -zxf icu4c-50_1_2-src.tgz
cd icu/source
mkdir bin
./configure
# собираем утилиту pkgdata
cd tools/pkgdata/
make
cd ../../
# теперь обновим файл данных
cd data/in/
# копируем скаченные ранее файлы в эту папку и добавляем их в файл данных
../../bin/pkgdata -a zoneinfo64.res icudt50l.dat
../../bin/pkgdata -a metaZones.res icudt50l.dat
../../bin/pkgdata -a timezoneTypes.res icudt50l.dat
../../bin/pkgdata -a windowsZones.res icudt50l.dat
# после чего запускаем сборку
cd ../../
make
В принципе, на этом можно остановится и после сборки заменить в системе библиотеку из /usr/lib64/ на новую версию ./lib/libicudata.so.50.1.2.
Я же собрал пакет:
yum install rpmrebuild
rpmrebuild -e -p --notest-install libicu-last-50.1.2-10.el6.remi.x86_64.rpm
По строчке вида
BuildRoot: /root/.tmp/rpmrebuild.42406/work/root
определяем, где находятся распакованные файлы пакета и заменяем libicudata на свежую версию, получившийся пакет (rpmbuild напишет полный путь после сборки) можно установить с указанием ключа — force, так как мы не меняли его версию.
Спасибо за внимание!
Автор: neolink
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/php-2/72615
Ссылки в тексте:
[1] исходники на сайте icu: http://apps.icu-project.org/icu-jsp/downloadPage.jsp?ver=50.1.2&base=cs&svn=release-50-1-2
[2] отсюда: http://source.icu-project.org/repos/icu/data/trunk/tzdata/icunew/2014i/44/le/
[3] Источник: http://habrahabr.ru/post/241447/
Нажмите здесь для печати.