php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #67127 setlocale LC_NUMERIC breaks DateTime microseconds
Submitted: 2014-04-24 09:47 UTC Modified: 2021-04-05 15:46 UTC
Votes:16
Avg. Score:4.2 ± 0.9
Reproduced:13 of 14 (92.9%)
Same Version:4 (30.8%)
Same OS:3 (23.1%)
From: honzap at gmail dot com Assigned: derick (profile)
Status: Not a bug Package: Date/time related
PHP Version: 5.4.27 OS: Linux (Debian Wheezy)
Private report: No CVE-ID: None
 [2014-04-24 09:47 UTC] honzap at gmail dot com
Description:
------------
I need using DateTime with microseconds. I've found some examples like at this page:
http://stackoverflow.com/questions/169428/php-datetime-microseconds-always-returns-0
I've used my own class extending \DateTime. Formatting still doesn't work in my application so I've looking for something bad and found setting setlocale(LC_ALL, ...) calling. 

I've found, setting LC_NUMERIC breaks down the function of microseconds. Testing script is at the attachment. It's probably caused because in my chosen locale the decimal point is comma (",") not point (".").

Test script:
---------------
date_default_timezone_set('Europe/Prague');

$time = microtime(true);
$micro_time = sprintf("%06d", ($time - floor($time)) * 1000000);

$date = new DateTime(date('Y-m-d H:i:s.' . $micro_time, $time));
echo $date->format("Y-m-d H:i:s.u") . " - OK\n";

setlocale(LC_NUMERIC, 'cs_CZ.utf8');

$date = new DateTime(date('Y-m-d H:i:s.' . $micro_time, $time));
echo $date->format("Y-m-d H:i:s.u") . " - BAD!\n";


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-06-03 22:16 UTC] wilfrid at digifactory dot fr
We have a problem link to this LC_NUMERIC issue : float numbers suddently get coma rather than point for decimal separator. 

It's extremely problematic as it's in several ecommerce websites.

Also, is rare and really random (kind of 1 per 10 000 entries). As it's the LC_NUMERIC, str_replace(",", ".", $str) doesn't work.

we are using PHP 5.4.26 on a debian.

On the same server, we noticed a similar problem with LC_TIME : 
setlocale(LC_TIME, 'fr_FR'); // fixed in the top of the php script.
and randomly, an average of 1 on 20 reload, we have a date displayed in english.
We noticed that putting the setlocale(LC_TIME, 'fr_FR'); just before the strftime('%A %d %B') seems to work arround the bug, for now.

VoilĂ , hope it can help !
 [2016-08-06 18:16 UTC] cmb@php.net
-Status: Open +Status: Analyzed -Assigned To: +Assigned To: derick
 [2016-08-06 18:16 UTC] cmb@php.net
I can confirm this issue. The culprit is in timelib_get_frac_nr()
where strtod() is used[1], which is locale dependend. Using
zend_strtod() instead would solve the issue, but that would make
timelib depending on the Zend engine, what is certainly not
desired.

Derick, what do you think about including some locale independent
strtod() replacement[2].

@wilfrid Your issue is unrelated to this bug report, and actually,
it is not a bug, but rather being caused by setlocale() not being
thread safe[3]. Consider to use the intl extension[4] instead.

[1] <https://github.com/derickr/timelib/blob/master/parse_date.re#L514>
[2] fe. <http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8/missing/strtod.c>
[3] <http://php.net/manual/en/function.setlocale.php#refsect1-function.setlocale-notes>
[4] <http://php.net/manual/en/intro.intl.php>
 [2017-10-24 05:24 UTC] kalle@php.net
-Status: Analyzed +Status: Assigned
 [2017-12-11 15:28 UTC] thflori at gmail dot com
This is related to the problem that double conversion does not work with LC_NUMERIC=cs_CZ.utf8 (or some other locale with , as decimal point like de_DE.utf8).

Test script:
------------
echo (double)'0.42';
setlocale(LC_NUMERIC, 'de_DE.utf8');
echo (double)'0.42';

Expected Output:
----------------
0.42
0,42

Actual Output:
--------------
0.42
0,42.0
 [2020-03-18 08:42 UTC] cmb@php.net
> This is related to the problem that double conversion does not
> work with LC_NUMERIC=cs_CZ.utf8 (or some other locale with , as
> decimal point like de_DE.utf8).

To be clear, double to string conversion works as intended for any
locale; it's just not the most sensible behavior[1].  Anyhow, this
bug is not about that issue (see originally supplied test script).

[1] <https://wiki.php.net/rfc/locale_independent_float_to_string>
 [2021-04-05 15:46 UTC] derick@php.net
-Status: Assigned +Status: Not a bug
 [2021-04-05 15:46 UTC] derick@php.net
Thank you for taking the time to report a problem with PHP.
Unfortunately you are not using a current version of PHP --
the problem might already be fixed. Please download a new
PHP version from http://www.php.net/downloads.php

If you are able to reproduce the bug with one of the latest
versions of PHP, please change the PHP version on this bug report
to the version you tested and change the status back to "Open".
Again, thank you for your continued support of PHP.

This appears to have been fixed in PHP 7.2 already.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 15:01:30 2024 UTC