|
| 1 | +--TEST-- |
| 2 | +Bug #73858: diff() of two relative/described DateTimes is wrong |
| 3 | +--FILE-- |
| 4 | +<?php |
| 5 | +/* |
| 6 | +In the "verbose setup method" I'm trying setup the DateTime object myself |
| 7 | +to see if it's the format string which is parsed in correctly or if it's the DateTime |
| 8 | +object which is breaking stuff. From the testing it appears DateTime is broken somehow. |
| 9 | +*/ |
| 10 | +$ss = 'first day of last month midnight'; |
| 11 | +$es = 'first day of this month midnight - 1 second'; |
| 12 | + |
| 13 | +$s = new DateTime($ss); |
| 14 | +$e = new DateTime($es); |
| 15 | +$d= $e->diff($s); |
| 16 | +var_dump($d->days); // 0 ... but should be 30 |
| 17 | + |
| 18 | +$s = (new DateTime(null))->setTimestamp(strtotime($ss)); // verbose setup method |
| 19 | +$e = (new DateTime(null))->setTimestamp(strtotime($es)); // verbose setup method |
| 20 | +$d = $e->diff($s); |
| 21 | +var_dump($d->days); // 30 ... and should be 30 |
| 22 | + |
| 23 | +/* |
| 24 | +Next we will try mix/match the code to see what happens, surprisingly it seems that the end date ($e) |
| 25 | +is the important one, if it uses the verbose method it returns the correct values. |
| 26 | +*/ |
| 27 | +$s = (new DateTime(null))->setTimestamp(strtotime($ss)); // verbose setup method |
| 28 | +$e = new DateTime($es); |
| 29 | +$d= $e->diff($s); |
| 30 | +var_dump($d->days); // 0 ... but should be 30 |
| 31 | + |
| 32 | +$s = new DateTime($ss); |
| 33 | +$e = (new DateTime(null))->setTimestamp(strtotime($es)); // verbose setup method |
| 34 | +$d= $e->diff($s); |
| 35 | +var_dump($d->days); // 30 ... and should be 30 |
| 36 | + |
| 37 | +/* |
| 38 | +This test just proves that the $e date is important BUT NOT because it's the one we call the diff() method |
| 39 | +on, that's just coincidental that seems to imply that the "- 1 second" in the date string is the problem. |
| 40 | +*/ |
| 41 | +$s = new DateTime($ss); |
| 42 | +$e = (new DateTime(null))->setTimestamp(strtotime($es)); // verbose setup method |
| 43 | +$d= $s->diff($e); |
| 44 | +var_dump($d->days); // 30 ... and should be 30 |
| 45 | + |
| 46 | +/* |
| 47 | +[Workaround] |
| 48 | +This final test seems to prove that the input string is important and that the "- 1 secord" has a negative knock-on |
| 49 | +effect on the results of the diff. By modifying the datetime with ->modify everything works as expected ... |
| 50 | +it just means you have to be careful of how we work with DateTimes . |
| 51 | +*/ |
| 52 | +$s = new DateTime($ss); |
| 53 | +$e = new DateTime('first day of this month midnight'); |
| 54 | +$e->modify('- 1 second'); |
| 55 | +var_dump($e->diff($s)->days); // 30 ... and should be 30 |
| 56 | +?> |
| 57 | +--EXPECT-- |
| 58 | +int(30) |
| 59 | +int(30) |
| 60 | +int(30) |
| 61 | +int(30) |
| 62 | +int(30) |
| 63 | +int(30) |
0 commit comments