I got PHP 7.0.8 (FPM) running on FreeBSD 10.1 and nginx. I need to display time in preferred format by the country where user resides.
setlocale(LC_ALL, "ru_RU.UTF-8");
date_default_timezone_set("Europe/Moscow");
echo strftime('%X', time());
// Returns 21:23:12 (correct) because 24-hr format is preferred in Russia.
setlocale(LC_ALL, "en_US.UTF-8");
date_default_timezone_set("America/New_York");
echo strftime('%X', time());
// Returns 21:23:12 (incorrect) must return 9:23:12 pm as preferred format in U.S.
This looks like an issue with my server or PHP version, because other users are getting correct results.
locale -a
return contains both ru_RU.UTF-8
and en_US.UTF-8
.
echo setlocale(LC_ALL, "en_US.UTF-8")
returns correct locale.
No special configuration is applied.
Please help me to resolve this. Thanks.
%X Preferred time representation based on locale, without the date
P.S. Preferred date %x
works correctly displaying dd.mm.yyyy for Russia and mm/dd/yyyy for U.S.
Same on FreeBSD 10.3:
php -r 'date_default_timezone_set("Europe/Paris"); var_dump(setlocale(LC_ALL, "en_US.UTF-8"), strftime("%X", time()));'
string(11) "en_US.UTF-8"
string(8) "15:03:07"
First, ls -l /usr/share/locale/en_US.UTF-8/LC_TIME
returns:
/usr/share/locale/en_US.UTF-8/LC_TIME@ -> ../en_US.ISO8859-1/LC_TIME
So en_US.UTF-8 is, in fact, a symlink to en_US.ISO8859-1.
Then, If we look into /usr/src/share/timedef/en_US.ISO8859-1.src (you need sources installed), we find:
#
# X_fmt
#
%H:%M:%S
Which explains the actual result when you would expect %I:%M:%S %p
(or %r
).
Possible solutions:
handle this specific case:
echo strftime(0 === strpos(setlocale(LC_ALL, '0'), 'en_US') ? '%r' : '%X');
prefer using IntlDateFormatter which does not rely on system-locales (assumed by ICU library). Eg:
$timefmt = new IntlDateFormatter('en_US', IntlDateFormatter::NONE, IntlDateFormatter::MEDIUM);
$timefmt->format(date_create());
1 it seems that X_fmt
is valued to %I:%M:%S %p
in trunk and 11-STABLE
Update:
X_fmt
was reverted since (ie on FreeBSD >= 11, X_fmt
is still defined as %H:%M:%S
)