Bug #62327 [Opn->Nab]: Calculation error in DateTime::add() or DateTime::diff()

From: 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

« previous php.bugs (#237194) next »