Bug #62327 [Opn->Nab]: Calculation error in DateTime::add() or DateTime::diff()
| From: | cmb@php.net | Date: | Thu, 14 Oct 2021 13:08:45 +0000 |
| Subject: | Bug #62327 [Opn->Nab]: Calculation error in DateTime::add() or DateTime::diff() | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-237194@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=62327&edit=1
ID: 62327
Updated by: cmb@php.net
Reported by: helmut at qweb dot at
Summary: Calculation error in DateTime::add() or
DateTime::diff()
-Status: Open
+Status: Not a bug
Type: Bug
Package: Date/time related
Operating System: Linux, Windows
PHP Version: Irrelevant
-Assigned To:
+Assigned To: cmb
Block user comment: N
Private report: N
New Comment:
Indeed, this is not a bug, because a DateInterval is not
necessarily a time span in seconds.
> Params: 2012-06-25, 2012-07-27, 2012-07-02
> Result: 2012-08-03
The difference between the first two dates is 1 month and 2 days.
Adding that to the third date gives 2012-07-04. See
<https://3v4l.org/7d0dn>.
Previous Comments:
------------------------------------------------------------------------
[2021-07-27 03:52:49] antonino dot spampinato86 at gmail dot com
Is the expected result, diff is likely to be unique for two dates. The php arithmetic is not one to
one like the human one, in fact a month can be 30 days, 31, 28 or 29 if leap year. I show you the
raw code, where I have voluntarily created and overwritten the variable $interval, if you try to
comment on the second one will get an incorrect result but this is because the calculation is not
one to one but as I explained above (diff is almost always unique ).
https://3v4l.org/MKeKE
This not a bug :)
------------------------------------------------------------------------
[2017-07-09 13:54:12] xKhorasan+php at gmail dot com
Submitted a pull request to derickr/timelib.
https://github.com/derickr/timelib/pull/15
------------------------------------------------------------------------
[2012-06-14 19:04:18] helmut at qweb dot at
Description:
------------
The task was to shift a date-interval like [ begin: 2012-05-07, end: 2012-06-01 ] to another begin
date like 2012-05-21 - an end date 2012-06-15 is expected (first example). The function
shift_datetimeobject() uses DateTime::diff() and DateTime::add() to calculate the end date - it
fails in the 3rd of 4 attempts.
The second function shift_timestamp() uses timestamp to solve the same task. it works like expected.
The bug was found on Windows Server 2008/Apache 2.4.2/PHP 5.4.4 and on Debian Linux squeeze/PHP
5.3.3-7+squeeze9 with Suhosin-Patch/cli and libapache2-mod-php5 5.3.3-7+squeeze9
Test script:
---------------
function shift_datetimeobject($begin1, $end1, $begin2) {
$dt_begin1 = new DateTime($begin1);
$dt_end1 = new DateTime($end1);
$span = $dt_begin1->diff($dt_end1);
$dt_return = new DateTime($begin2);
return array($dt_return->add($span), $span);
}
function shift_timestamp($begin1, $end1, $begin2) {
$dt_begin1 = new DateTime($begin1);
$st_begin1 = $dt_begin1->getTimestamp();
$dt_end1 = new DateTime($end1);
$st_end1 = $dt_end1->getTimestamp();
$span = $st_end1 - $st_begin1;
$dt_begin2 = new DateTime($begin2);
$st_begin2 = $dt_begin2->getTimestamp();
$st_end2 = $st_begin2 + $span;
$dt_end2 = new DateTime();
return $dt_end2->setTimestamp($st_end2);
}
$params = array(
array('2012-05-07', '2012-06-01', '2012-05-21'),
array('2012-06-11', '2012-07-13', '2012-06-18'),
array('2012-06-25', '2012-07-27', '2012-07-02'),
array('2012-07-09', '2012-07-27', '2012-07-16'),
);
foreach ($params as $p) {
$erg_object = shift_datetimeobject($p[0], $p[1], $p[2]);
$erg_stamp = shift_timestamp($p[0], $p[1], $p[2]);
printf("Params: %s, %s, %s\n", $p[0], $p[1], $p[2]);
printf('$erg_stamp = %s' . "\n",
$erg_stamp->format('Y-m-d'));
printf('$erg_object[0] = %s' . "\n",
$erg_object[0]->format('Y-m-d'));
printf("span (object) = %s\n", $erg_object[1]->format('%a days
%H:%I:%S'));
if ($erg_object[0] == $erg_stamp) {
echo "OK";
} else {
echo "WRONG!";
}
echo "\n\n";
}
Expected result:
----------------
Params: 2012-05-07, 2012-06-01, 2012-05-21
Result: 2012-06-15
Params: 2012-06-11, 2012-07-13, 2012-06-18
Result: 2012-07-20
Params: 2012-06-25, 2012-07-27, 2012-07-02
Result: 2012-08-03
Params: 2012-07-09, 2012-07-27, 2012-07-16
Result: 2012-08-03
Actual result:
--------------
Params: 2012-05-07, 2012-06-01, 2012-05-21
$erg_stamp = 2012-06-15
$erg_object[0] = 2012-06-15
span (object) = 25 days 00:00:00
OK
Params: 2012-06-11, 2012-07-13, 2012-06-18
$erg_stamp = 2012-07-20
$erg_object[0] = 2012-07-20
span (object) = 32 days 00:00:00
OK
Params: 2012-06-25, 2012-07-27, 2012-07-02
$erg_stamp = 2012-08-03
$erg_object[0] = 2012-08-04
span (object) = 32 days 00:00:00
WRONG!
Params: 2012-07-09, 2012-07-27, 2012-07-16
$erg_stamp = 2012-08-03
$erg_object[0] = 2012-08-03
span (object) = 18 days 00:00:00
OK
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=62327&edit=1