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