deb.sury.org
deb.sury.org copied to clipboard
IntlDateFormatter uses wrong TimeZoneDB
System tzdata is correct, it's 2017c and system clock set to same TZ show correct time. But,
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.5 LTS
Release: 14.04
Codename: trusty
$ dpkg --list tzdata
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==================-==============-==============-==========================================
ii tzdata 2017c-0ubuntu0 all time zone and daylight-saving time data
$ date +%z
+0300
$ php -r 'print \IntlTimeZone::createTimeZone("Europe/Moscow")->getRawOffset() / 1000 / 60 / 60;'
4
$ php -r 'print \IntlTimeZone::createTimeZone("Europe/Moscow")->getTZDataVersion();'
2013g
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.5 LTS
Release: 16.04
Codename: xenial
$ dpkg --list tzdata
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==================-==============-==============-==========================================
ii tzdata 2017c-0ubuntu0 all time zone and daylight-saving time data
$ date +%z
+0300
$ php -r 'print \IntlTimeZone::createTimeZone("Europe/Moscow")->getRawOffset() / 1000 / 60 / 60;'
3
$ php -r 'print \IntlTimeZone::createTimeZone("Europe/Moscow")->getTZDataVersion();'
2015b
PHP 7.2.9 in both cases. Sorry I've missed that bit.
intl
extension uses libicu
from (Debian|Ubuntu), which uses bundled timezones, which are (always) outdated.
You need to download latest timezone db's and use ICU_DATA
environment variable for PHP.
I've got latest ICU timezones in /opt/icu/icudt57l
directory. Some google-fu will explain the directory naming etc.
ICU_DATA=/opt/icu php -r 'print \IntlTimeZone::createTimeZone("Europe/Moscow")->getTZDataVersion();'
2018e
Given repeated claims that "PHP on ubuntu uses system tzdata"…
¯\_(ツ)_/¯
$ lsb_release -cs
xenial
$ php -r 'print \IntlTimeZone::createTimeZone("Europe/Moscow")->getTZDataVersion();'
2015b
$ ICU_DATA=/opt/icu php -r 'print \IntlTimeZone::createTimeZone("Europe/Moscow")->getTZDataVersion();'
2018e
I guess I'm lucky to know how to wrest both upstart and systemd to work out identical results. But frankly… this is a nuisance.
So... PHP built by this repo does not use the systems tzdata? If not, could you please include the debian patch @oerdnj ?
PHP intl
extension functions use ICU, which has its own database and cannot be patched to use system tzdata.
Regular date/time stuff (like DateTimeZone
) can be patched to use system tzdata - but this adds a lot of syscall overhead and I would advise against this. Instead you should install and use timezonedb from PECL. This could be a good candidate for @oerdnj to package for Debian and Ubuntu.
In order to install timezonedb you'd have to install "php7-dev" (because it needs phpize
). Is this a good idea?
You could create a new issue and request packaging php-timezonedb
🙂 I know at least I would benefit from that.
@oerdnj Whats your take on this?
Mh, in the mean time we could build the package ourselves. Quick google brings up these two guides: https://blog.remibergsma.com/2012/04/05/howto-create-php5-pecl-debian-packages/ and https://www.dotdeb.org/2008/09/25/how-to-package-php-extensions-by-yourself/
Updating timezonedb
won't solve intl
issue.
$ php --ri timezonedb
timezonedb
Alternative Timezone Database => enabled
Timezone Database Version => 2018.5
$ php -r 'print \IntlTimeZone::createTimeZone("Europe/Moscow")->getTZDataVersion();'
2016b
Packaging php-timezonedb seems like fine idea.
As for libicu, you need to fill bug with Ubuntu to update tzdata in libicu.
So the only working fix for the intl extension (atm) is using the ICU_DATA env variable as @todeveni pointed out?
Only works for CLI. All my attempts to teach FPM to pick the new data have failed so far.
I've got env[ICU_DATA] = /opt/icu
in all my /etc/php/7.2/fpm/pool.d/example.conf
files.
Ok, found the solution. In pool config, set:
env[ICU_DATA] = /opt/icu