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