php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #69378 Incorrect Result for DateTime::sub()
Submitted: 2015-04-05 14:47 UTC Modified: 2021-04-05 16:12 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: support at eggplantsd dot com Assigned:
Status: Not a bug Package: Date/time related
PHP Version: 5.4.39 OS: Debian Wheezy x64
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: support at eggplantsd dot com
New email:
PHP Version: OS:

 

 [2015-04-05 14:47 UTC] support at eggplantsd dot com
Description:
------------
B - (B - A) == A SHOULD HOLD TRUE
DOES HOLD TRUE USING UNIX TIMESTAMP MATH
DOES NOT HOLD TRUE USING DateTime:sub()

Test script:
---------------
/*
   METHODOLOGY:
      B - (B - A) == A SHOULD HOLD TRUE
      DOES HOLD TRUE USING UNIX TIMESTAMP MATH
      DOES NOT HOLD TRUE USING DateTime:sub()
*/

$DF_MYSQL = 'Y-m-d H:i:s';

$dtB = DateTime::createFromFormat($DF_MYSQL, '2015-04-02 09:44:47');
$dtA = DateTime::createFromFormat($DF_MYSQL, '2014-02-16 02:00:00');

// DateInterval: B-A
$diDiff = $dtA->diff($dtB);

// Unix Timestamp: B-A
$tsDiff = $dtB->getTimestamp() - $dtA->getTimestamp();

// REPORT DIFFERENCES
/*
   NOTE: DIFFERENCE B-A IS
      $y => 1
      $m => 1
      $d => 17
      $h => 7
      $i => 44
      $s => 47
*/
print_r($diDiff);

// Unix Timestamp: CALCULATE A FROM (B - DIFFERENCE) AND REPORT
// NOTE: CORRECT RESULT, SAME AS $dtA: 2014-02-16 02:00:00
$tsShift = $dtB->getTimestamp() - $tsDiff;
$dtOut = new DateTime();
$dtOut->setTimestamp($tsShift);
print_r($dtOut);

// DateInterval: CALCULATE A FROM (B - DIFFERENCE) AND REPORT
// NOTE: INCORRECT RESULT, DIFFERENT FROM $dtA: 2014-02-13 02:00:00
$dtB->sub($diDiff);
print_r($dtB);

Expected result:
----------------
SEE SCRIPT COMMENTS

Actual result:
--------------
SEE SCRIPT COMMENTS

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-04-14 07:06 UTC] andreas at heigl dot org
The change seems to have been introduces in PHP5.3.3 as can be seen in http://3v4l.org/mUeRk.
 [2021-01-21 14:51 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2021-01-21 14:51 UTC] cmb@php.net
Date/time arithmetic is inherently hard.  In this case it is about
the order of the operations:

2014-04-02 - 17d = 2014-03-16
2014-03-16 -  1m = 2014-02-16

vs.

2014-04-02 -  1m = 2014-03-02
2014-03-02 - 17d = 2014-02-13
 [2021-04-05 16:12 UTC] derick@php.net
-Status: Verified +Status: Not a bug
 [2021-04-05 16:12 UTC] derick@php.net
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

DateTime::diff documentation:

"The return value more specifically represents the interval to apply to the original object ($this or $originObject) to arrive at the $targetObject. This process is not always reversible. "

As @cmb already explained, that is the case here.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 10:01:26 2024 UTC