|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #53831 DateInterval constructor does not handle valid ISO 8601 strings
Submitted: 2011-01-24 18:41 UTC Modified: 2020-02-28 00:58 UTC
Avg. Score:4.4 ± 0.9
Reproduced:47 of 47 (100.0%)
Same Version:11 (23.4%)
Same OS:9 (19.1%)
From: pallinger at dsd dot sztaki dot hu Assigned: derick (profile)
Status: Not a bug Package: Date/time related
PHP Version: 5.3.5 OS: ubuntu linux 10.10
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
From: pallinger at dsd dot sztaki dot hu
New email:
PHP Version: OS:


 [2011-01-24 18:41 UTC] pallinger at dsd dot sztaki dot hu
From manual page:
The documentation says that "Each duration period is represented by an integer value followed by a period designator.", however, the ISO 8601 allows non-integer values for the last number (
This is quite important if I want to parse XML data which contains millisecond-precision durations, as the seconds will surely not be integers.

Test script:
   var_dump(new DateInterval('PT1.1S'));

Expected result:
Should print out a valid DateInterval object, eg.:
object(DateInterval)#1 (8) {
It could also include a millisecond/microsecond/nanosecond field to accomodate additional precision. However, if the durations that are stored are still integers, it would be difficult to handle durations like "P0.5Y".

Actual result:
PHP Fatal error:  Uncaught exception 'Exception' with message 'DateInterval::__construct(): Unknown or bad format (PT1.1S)' in -:1
Stack trace:
#0 -(1): DateInterval->__construct('PT1.1S')
#1 {main}
  thrown in - on line 1


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2011-10-12 16:09 UTC] dagguh at gmail dot com

This decimal fraction may be specified with either a comma or a full stop, as in 
"P0,5Y" or "P0.5Y".

Remember to accept both comma and a full stop.
 [2012-04-02 10:47 UTC] jdp2234 at hotmail dot com
Quick class to get around it, while the bug still exists...
class DateIntervalFractions extends DateInterval {
	public $milliseconds;
	public function __construct($interval_spec) {
		$this->milliseconds = 0;
		$matches = array();
		foreach ($matches[0] as $result)
			$original = $result;
			list($seconds,$milliseconds) = 
			$this->milliseconds = $milliseconds / 
pow(10,strlen($milliseconds) - 3);

                        // Replace the milliseconds back to seconds,
                        // and let the original constructor do the rest.
			$interval_spec = str_replace($original,$seconds . 
 [2017-12-05 22:46 UTC] sloanlance+php dot net at gmail dot com
I'm surprised this bug has persisted since 2011-01-24.  This seems to have been implemented incorrectly from the beginning.  ISO 8601 has mentioned support for fractional parts since at least 2004.

That is, it supports a decimal fraction to the smallest time value in a representation.

For example, the following representations are valid ISO 8601 intervals, but will cause the DateInterval constructor to throw exceptions:


I appreciate the attempted workaround by "jdp2234 at hotmail dot com", but it appears to only support milliseconds.  It doesn't seem to address fractions in other parts of interval representations.
 [2019-01-10 19:15 UTC] mdwyer at michaelmdwyer dot com
This appears to still be an issue with PHP 7.2, despite them adding a microseconds field to DateInterval.  My current workaround is:

        $fractional = new DateInterval('PT0S');
        $fractional->f = ".{$microseconds}";
        $fractional->invert = $seconds < 0;

        return (new DateTime("@{$seconds}"))->add($fractional);
 [2020-02-27 19:12 UTC]
-Status: Open +Status: Verified -Assigned To: +Assigned To: derick
 [2020-02-27 19:12 UTC]
This may be considered more of a feature request than a bug, however, I'm assigning to Derrick and pinging them here.

When I looked at "Appendix A. ISO 8601 Collected ABNF" of RFC3339, I only see the definition of Seconds Duration as DIGIT, not fraction:


   dur-second        = 1*DIGIT "S"
   dur-minute        = 1*DIGIT "M" [dur-second]
   dur-hour          = 1*DIGIT "H" [dur-minute]
   dur-time          = "T" (dur-hour / dur-minute / dur-second)
   dur-day           = 1*DIGIT "D"
   dur-week          = 1*DIGIT "W"
   dur-month         = 1*DIGIT "M" [dur-day]
   dur-year          = 1*DIGIT "Y" [dur-month]
   dur-date          = (dur-day / dur-month / dur-year) [dur-time]

Additionally, section 5.3 of the RFC may seem to indicate that this not required by the specification:


5.3. Rarely Used Options

   A format which includes rarely used options is likely to cause
   interoperability problems.  This is because rarely used options are
   less likely to be used in alpha or beta testing, so bugs in parsing
   are less likely to be discovered.  Rarely used options should be made
   mandatory or omitted for the sake of interoperability whenever

   The format defined below includes only one rarely used option:
   fractions of a second.  It is expected that this will be used only by
   applications which require strict ordering of date/time stamps or
   which have an unusual precision requirement.


However, I'll leave this to Derick to decide. It does seem to be a highly sought after feature and it would make sense to add it in the interval spec.

Derick, any thoughts on this?
 [2020-02-28 00:56 UTC]
-Status: Verified +Status: Open
 [2020-02-28 00:56 UTC]
-Status: Assigned +Status: Open
 [2020-02-28 00:58 UTC]
-Status: Assigned +Status: Not a bug
 [2020-02-28 00:58 UTC]
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at and the instructions on how to report
a bug at


This feature won't be implemented in php at the current time.
 [2020-03-28 22:56 UTC] pegasus at vaultwiki dot org
According to the RFC cited as the reason for closing this report:
"This information is based on the 1988 version of ISO 8601.  There may
   be some changes in the 2000 revision."

However, when discussing the basis for the accepted formats for DateInterval, the PHP documentation ( links not to the cited RFC but to the Wikipedia page for ISO 8601, which reflects more recent versions of the ISO that were written after 1988. If PHP devs insist this is not a bug, then the documentation should be updated to point to the RFC, and not to a page that discusses features of the ISO that PHP has not implemented.
 [2020-03-29 04:31 UTC] pegasus at vaultwiki dot org
For reference, here is a more recent version of ISO 8601 that I've found (from 2000).
The relevant section is 5.5.3. It states:
"If necessary for a particular application the lowest order component may have a decimal fraction. The decimal
fraction shall be divided from the integer part by the decimal sign specified in ISO 31-0: i.e. the comma [,] or
full stop [.]. Of these, the comma is the preferred sign. The decimal fraction shall at least have one digit. If the
magnitude of the number is less than unity, the decimal sign shall be preceded by a zero (see ISO 31-0)."
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Tue Aug 11 02:01:24 2020 UTC