DateTime::diff weired result

[亡魂溺海] 提交于 2019-12-19 04:57:17

问题


I use DateTime::diff to compare two DateTime, but the result is very weird as if abs($date1 - $date2) != abs($date2 - $date1).

$date1 = new DateTime("1980-11-21 00:00:00");
$date2 = new DateTime("1981-11-20 00:00:00");
var_dump($date1->diff($date2,true)->days);
var_dump($date2->diff($date1,true)->days);
var_dump($date1->diff($date2,true)->format("%Y-%m-%d %H:%i:%s"));
var_dump($date2->diff($date1,true)->format("%Y-%m-%d %H:%i:%s"));

Which returns:

int(364)
int(364)
string(15) "00-11-30 00:0:0"
string(15) "00-11-29 00:0:0"

Demo


回答1:


The behavior is correct. Both date intervals represent same number of days (364). The month and date part represent the period that needs to be added to/subtracted from first date to reach second date:

1981-11-20 minus 1980-11-21 represents an interval of 11 month 30 day
1980-11-21 + 11 month = 1981-10-21
1981-10-21 + 30 day   = 1981-10-21

1980-11-21 minus 1981-11-20 represents an interval of 11 month 29 day
1981-11-20 - 11 month = 1980-12-20
1980-12-20 - 29 day   = 1980-11-21

A simpler example would be Oct 21 ... Dec 20:

  • You need to add 1 month 29 days to Oct 21 to reach Dec 20 (note that month before Dec has 30 days)
  • But ... you need to subtract 1 month 30 days from Dec 20 to reach Oct 21. Oct itself has 31 days which explains the difference.



回答2:


Why not subtract min from max?
Pseudo code:

$diff = max($date1, $date2) - min($date1, $date2)

That way you should always get the same and correct result.




回答3:


The result seems wired, but is correct: It is explained by some months having 30 or 31 (or 28) days. If you would execute this example for October

    $date1 = new DateTime("1980-10-21 00:00:00");
    $date2 = new DateTime("1981-10-20 00:00:00");
    var_dump($date1->diff($date2,true)->format("%Y-%m-%d %H:%i:%s"));
    var_dump($date2->diff($date1,true)->format("%Y-%m-%d %H:%i:%s"));
    var_dump($date1->diff($date2,true)->format("%Y-%m-%d %H:%i:%s") == $date2->diff($date1,true)->format("%Y-%m-%d %H:%i:%s"));
string(15) "00-11-29 00:0:0"
string(15) "00-11-30 00:0:0"
bool(false)

or February

string(15) "00-11-30 00:0:0"
string(15) "00-11-28 00:0:0"
bool(false)

Yet

var_dump($date1->diff($date2,true)->format("%a"));

will always show

string(3) "365"



回答4:


Ok so just to state my comment as an answer. My guess is that this is the expected behaviour since it's a different amount of days depending on if you go forwards or backwards in time. Imagine going from yesterday to today over a year, that'd be 366 days since you have to round a whole year plus 1 day. And from today to yesterday (last year) would be only 364 days for the same reason, it's whole year minus one day. As for the solution, the option that @Andreas suggested is the way to go here.



来源:https://stackoverflow.com/questions/58954032/datetimediff-weired-result

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!