Bug #62327 [Com]: Calculation error in DateTime::add() or DateTime::diff()
| From: | antonino dot spampinato86 at gmail dot com | Date: | Tue, 27 Jul 2021 03:52:49 +0000 |
| Subject: | Bug #62327 [Com]: Calculation error in DateTime::add() or DateTime::diff() | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-235388@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
Comment by: antonino dot spampinato86 at gmail dot com
Reported by: helmut at qweb dot at
Summary: Calculation error in DateTime::add() or
DateTime::diff()
Status: Open
Type: Bug
Package: Date/time related
Operating System: Linux, Windows
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
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 :)
Previous Comments:
------------------------------------------------------------------------
[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