3v4l.org

run code in 300+ PHP versions simultaneously
<?php $ss = 'first day of this month midnight'; $es = 'first day of next month midnight - 1 second'; $s = new DateTime($ss); $e = new DateTime($es); $d= $e->diff($s); var_dump($d->days); // 0 ... but should be 30 // This should be 0 because: // * "first day of last month midnight" is 2016-12-01T00:00:00" // * "first day of this month midnight - 1 second" is 2016-12-01T23:59:59+11:00 // because right to left. First the expression "midnight -1 second" "first day of this month" $s = (new DateTime(null))->setTimestamp(strtotime($ss)); // verbose setup method $e = (new DateTime(null))->setTimestamp(strtotime($es)); // verbose setup method $d = $e->diff($s); var_dump($d->days); // 30 ... and should be 30 /* Next we will try mix/match the code to see what happens, surprisingly it seems that the end date ($e) is the important one, if it uses the verbose method it returns the correct values. */ $s = (new DateTime(null))->setTimestamp(strtotime($ss)); // verbose setup method $e = new DateTime($es); $d= $e->diff($s); var_dump($d->days); // 0 ... but should be 30 $s = new DateTime($ss); $e = (new DateTime(null))->setTimestamp(strtotime($es)); // verbose setup method $d= $e->diff($s); var_dump($d->days); // 30 ... and should be 30 /* This test just proves that the $e date is important BUT NOT because it's the one we call the diff() method on, that's just coincidental that seems to imply that the "- 1 second" in the date string is the problem. */ $s = new DateTime($ss); $e = (new DateTime(null))->setTimestamp(strtotime($es)); // verbose setup method $d= $s->diff($e); var_dump($d->days); // 30 ... and should be 30 /* [Workaround] This final test seems to prove that the input string is important and that the "- 1 secord" has a negative knock-on effect on the results of the diff. By modifying the datetime with ->modify everything works as expected ... it just means you have to be careful of how we work with DateTimes . */ $s = new DateTime($ss); $e = new DateTime('first day of this month midnight'); $e->modify('- 1 second'); var_dump($e->diff($s)->days); // 30 ... and should be 30 echo "\n\n Same stuff with DateTimeImmutable\n"; $s = new DateTimeImmutable($ss); $e = new DateTimeImmutable($es); $d= $e->diff($s); var_dump($d->days); // 0 ... but should be 30 $s = (new DateTimeImmutable(null))->setTimestamp(strtotime($ss)); // verbose setup method $e = (new DateTimeImmutable(null))->setTimestamp(strtotime($es)); // verbose setup method $d = $e->diff($s); var_dump($d->days); // 30 ... and should be 30 /* Next we will try mix/match the code to see what happens, surprisingly it seems that the end date ($e) is the important one, if it uses the verbose method it returns the correct values. */ $s = (new DateTimeImmutable(null))->setTimestamp(strtotime($ss)); // verbose setup method $e = new DateTimeImmutable($es); $d= $e->diff($s); var_dump($d->days); // 0 ... but should be 30 $s = new DateTimeImmutable($ss); $e = (new DateTimeImmutable(null))->setTimestamp(strtotime($es)); // verbose setup method $d= $e->diff($s); var_dump($d->days); // 30 ... and should be 30 /* This test just proves that the $e date is important BUT NOT because it's the one we call the diff() method on, that's just coincidental that seems to imply that the "- 1 second" in the date string is the problem. */ $s = new DateTimeImmutable($ss); $e = (new DateTimeImmutable(null))->setTimestamp(strtotime($es)); // verbose setup method $d= $s->diff($e); var_dump($d->days); // 30 ... and should be 30 /* [Workaround] This final test seems to prove that the input string is important and that the "- 1 secord" has a negative knock-on effect on the results of the diff. By modifying the datetime with ->modify everything works as expected ... it just means you have to be careful of how we work with DateTimes . */ $s = new DateTimeImmutable($ss); $e = new DateTimeImmutable('first day of this month midnight'); $e->modify('- 1 second'); var_dump($e->diff($s)->days); // 30 ... and should be 30
Output for 8.1.0 - 8.1.28, 8.2.0 - 8.2.18, 8.3.0 - 8.3.4, 8.3.6
int(30) Deprecated: DateTime::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 13 Deprecated: DateTime::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 14 int(30) Deprecated: DateTime::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 21 int(30) Deprecated: DateTime::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 26 int(30) Deprecated: DateTime::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 34 int(30) int(0) Same stuff with DateTimeImmutable int(30) Deprecated: DateTimeImmutable::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 55 Deprecated: DateTimeImmutable::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 56 int(30) Deprecated: DateTimeImmutable::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 63 int(30) Deprecated: DateTimeImmutable::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 68 int(30) Deprecated: DateTimeImmutable::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 76 int(30) int(0)
Output for 8.3.5
Warning: PHP Startup: Unable to load dynamic library 'sodium.so' (tried: /usr/lib/php/8.3.5/modules/sodium.so (libsodium.so.23: cannot open shared object file: No such file or directory), /usr/lib/php/8.3.5/modules/sodium.so.so (/usr/lib/php/8.3.5/modules/sodium.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 int(30) Deprecated: DateTime::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 13 Deprecated: DateTime::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 14 int(30) Deprecated: DateTime::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 21 int(30) Deprecated: DateTime::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 26 int(30) Deprecated: DateTime::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 34 int(30) int(0) Same stuff with DateTimeImmutable int(30) Deprecated: DateTimeImmutable::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 55 Deprecated: DateTimeImmutable::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 56 int(30) Deprecated: DateTimeImmutable::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 63 int(30) Deprecated: DateTimeImmutable::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 68 int(30) Deprecated: DateTimeImmutable::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /in/hjFnN on line 76 int(30) int(0)
Output for 7.0.20, 7.1.5 - 7.1.25, 7.2.0 - 7.2.33, 7.3.0 - 7.3.33, 7.4.0 - 7.4.33, 8.0.0 - 8.0.30
int(30) int(30) int(30) int(30) int(30) int(0) Same stuff with DateTimeImmutable int(30) int(30) int(30) int(30) int(30) int(0)
Output for 5.6.0 - 5.6.29, 7.0.0 - 7.0.14, 7.1.0
int(0) int(30) int(0) int(30) int(30) int(0) Same stuff with DateTimeImmutable int(0) int(30) int(0) int(30) int(30) int(0)

preferences:
168.62 ms | 402 KiB | 209 Q