Req #53831 [Asn->Nab]: DateInterval constructor does not handle valid ISO 8601 strings
| From: | googleguy@php.net | Date: | Fri, 28 Feb 2020 00:58:09 +0000 |
| Subject: | Req #53831 [Asn->Nab]: DateInterval constructor does not handle valid ISO 8601 strings | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-225766@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=53831&edit=1
ID: 53831
Updated by: googleguy@php.net
Reported by: pallinger at dsd dot sztaki dot hu
Summary: DateInterval constructor does not handle valid ISO
8601 strings
-Status: Assigned
+Status: Not a bug
Type: Feature/Change Request
Package: Date/time related
Operating System: ubuntu linux 10.10
PHP Version: 5.3.5
Assigned To: derick
Block user comment: N
Private report: N
New Comment:
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
Closing.
This feature won't be implemented in php at the current time.
Previous Comments:
------------------------------------------------------------------------
[2020-02-27 19:12:44] googleguy@php.net
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:
Durations:
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
possible.
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?
------------------------------------------------------------------------
[2019-01-10 19:15:05] 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);
------------------------------------------------------------------------
[2017-12-05 22:46:04] 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:
P0.5Y
P2.3D
P1DT1.5H
PT585.829S
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.
------------------------------------------------------------------------
[2012-04-02 10:47:20] jdp2234 at hotmail dot com
http://joshp.me/dateinterval-milliseconds/
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();
preg_match_all("#([0-9]*[.,]?[0-9]*)
[S]#",$interval_spec,$matches);
foreach ($matches[0] as $result)
{
$original = $result;
list($seconds,$milliseconds) =
explode(".",substr($result,0,-1));
$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 .
"S",$interval_spec);
}
parent::__construct($interval_spec);
}
}
------------------------------------------------------------------------
[2011-10-12 16:09:31] dagguh at gmail dot com
http://en.wikipedia.org/wiki/Iso8601#Durations
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.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=53831
--
Edit this bug report at https://bugs.php.net/bug.php?id=53831&edit=1