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

Pull Requests

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-2025 The PHP Group
All rights reserved.
Last updated: Sun Jun 15 14:01:35 2025 UTC