php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51950 DateTime does not handle decimal fractions of ISO 8601 format
Submitted: 2010-05-30 19:56 UTC Modified: 2019-07-16 09:25 UTC
Votes:131
Avg. Score:4.3 ± 0.8
Reproduced:119 of 120 (99.2%)
Same Version:24 (20.2%)
Same OS:18 (15.1%)
From: jmf at durcommefaire dot net Assigned: cmb (profile)
Status: Not a bug Package: Date/time related
PHP Version: 5.3.2 OS: Ubuntu 10.04
Private report: No CVE-ID: None
 [2010-05-30 19:56 UTC] jmf at durcommefaire dot net
Description:
------------
DateTime does not handle decimal fractions of ISO 8601 format (cf. http://en.wikipedia.org/wiki/ISO_8601#Times)

This value has decimal fraction and is not recognized by DateTime :

$dateTime = DateTime::createFromFormat(
    DateTime::ISO8601,
    '2009-04-16T12:07:23.596Z'
);
// bool(false)
var_dump($dateTime);


The same value without the decimal fraction is recognized :

$dateTime = DateTime::createFromFormat(
    DateTime::ISO8601,
    '2009-04-16T12:07:23Z'
);
// object(DateTime)#2 (3) { ["date"]=>  string(19) "2009-04-16 12:07:23" ["timezone_type"]=>  int(2) ["timezone"]=>  string(1) "Z" }
var_dump($dateTime);


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-06-06 22:25 UTC] dtajchreber@php.net
-Assigned To: +Assigned To: deric
 [2010-06-06 22:25 UTC] dtajchreber@php.net
-Assigned To: deric +Assigned To: derick
 [2014-10-15 14:25 UTC] h dot kraal at tiw dot nl
This 4+ years old bug is still present in todays systems:
Ubuntu 10.04 / PHP 5.3.2-1ubuntu4.27
Ubuntu 12.04 / PHP 5.3.10-1ubuntu3.14
Ubuntu 14.04 / PHP 5.5.9-1ubuntu4.4
 [2014-11-12 23:48 UTC] dev at jonathanlidbeck dot com
This bug is present in PHP 5.5 for Windows.
 [2015-06-25 05:05 UTC] broncha at rajesharma dot com
Confirmed on Mac. PHP version 5.5.26
 [2015-12-01 09:28 UTC] seb at rootsandrain dot com
Still broken in PHP7:

https://3v4l.org/aKNVI
 [2016-08-07 14:51 UTC] cmb@php.net
-Status: Assigned +Status: Not a bug -Assigned To: derick +Assigned To: cmb
 [2016-08-07 14:51 UTC] cmb@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

DateTime::ISO8601 is defined to "Y-m-d\TH:i:sO"[1], so obviously
it doesn't accept microsecond fractions. If you expect these to be
given, use another format specifier, see <https://3v4l.org/ADn0l>.

If you want to accept different ISO-8601 date/time formats,
don't use date_create_from_format(), but rather date_create(),
see <https://3v4l.org/c879B>.

[1] <http://php.net/manual/en/class.datetime.php>
 [2018-12-05 13:40 UTC] christophe at gosiau dot be
I would like to refer to this Wikipedia article:
https://en.wikipedia.org/wiki/ISO_8601

It states:
A decimal mark, either a comma or a dot (without any preference as stated in resolution 10 of the 22nd General Conference CGPM in 2003,[14] but with a preference for a comma according to ISO 8601:2004)[15] is used as a separator between the time element and its fraction.
 [2019-07-16 08:59 UTC] divinity76 at gmail dot com
@CMB you're wrong imo. in the sample code provided, PHP is told to parse a valid ISO8601 date, and PHP fails to do so. that's a bug in my eyes. please explain how this is not a bug, is PHP not supposed to parse a ISO8601 date when told to do so?
 [2019-07-16 09:25 UTC] cmb@php.net
> PHP is told to parse a valid ISO8601 date

No.  It is told to use the DateTime::ISO8601 format,
and the docs[1] state:

| This format is not compatible with ISO-8601, but is left this
| way for backward compatibility reasons. Use DateTime::ATOM or
| DATE_ATOM for compatibility with ISO-8601 instead.

If you think DateTime::ISO8601 should be changed for PHP 8, please
pursue the RFC process[2].

[1] <https://www.php.net/manual/en/class.datetimeinterface.php#datetime.constants.iso8601>
[2] <https://wiki.php.net/rfc/howto>
 [2021-03-16 07:19 UTC] hooby404 at gmail dot com
For anyone reading this: 

DateTime::ATOM / DATE_ATOM suffers from exactly the same problem, and there's currently (as of PHP 8.0) no easy way to correctly handle milliseconds with built-in PHP functions.

If you want to read the ISO 8601 format as produced by Javascript's Date.toJSON() in PHP, you have to rely on third party tools. 

I recommend this one: https://carbon.nesbot.com/
 [2022-09-13 10:10 UTC] xrypak at gmail dot com
Here a value from [the documentation](https://www.php.net/manual/en/datetime.format.php) is used:

    $value = '2004-02-12T15:19:21+00:00';
    $dt = new DateTime($value);
    $formatted = $dt->format('c');
    $date = \DateTime::createFromFormat('c', $formatted);
    $errors = \DateTime::getLastErrors();

Now, this produces the following errors:
- The format separator does not match
- Trailing data

This is funny, because value equals the formatted value ????‍♀️.
$formatted === $value // TRUE

Why can't we parse the value PHP itself outputs?
 [2022-09-13 10:40 UTC] xrypak at gmail dot com
Sorry, this seems to be known issue.

Using DATE_ATOM / DateTimeInterface::ATOM will work for ISO 8601 string NOT containing decimal parts.

It does NOT work for strings with decimal parts, though.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Nov 22 02:01:28 2024 UTC