I discovered that a DateTime object in PHP can be compared to another as the ">" and "<" operators are overloaded.
Is it the same with DateInterval?
As I was trying to answer this question, I found something strange:
<?php $today = new DateTime(); $release = new DateTime('14-02-2012'); $building_time = new DateInterval('P15D'); var_dump($today->diff($release)); var_dump($building_time); var_dump($today->diff($release)>$building_time); var_dump($today->diff($release)<$building_time); if($today->diff($release) < $building_time){ echo 'oK'; }else{ echo 'Just a test'; }
It always echoes "Just a test". The var_dump outputs are:
object(DateInterval)#4 (8) { ["y"]=> int(0) ["m"]=> int(0) ["d"]=> int(18) ["h"]=> int(16) ["i"]=> int(49) ["s"]=> int(19) ["invert"]=> int(1) ["days"]=> int(18) } object(DateInterval)#3 (8) { ["y"]=> int(0) ["m"]=> int(0) ["d"]=> int(15) ["h"]=> int(0) ["i"]=> int(0) ["s"]=> int(0) ["invert"]=> int(0) ["days"]=> bool(false) } bool(false) bool(true)
When I try with a DateTime as "01-03-2012" everything works.
In short, comparing of DateInterval
objects is not currently supported by default (as of php 5.6).
As you already know, the DateTime
Objects are comparable.
A way to achieve the desired result, is to subtract or add the DateInterval
from a DateTime
object and compare the two to determine the difference.
Example: https://3v4l.org/kjJPg
$buildDate = new DateTime('2012-02-15'); $releaseDate = clone $buildDate; $releaseDate->setDate(2012, 2, 14); $buildDate->add(new DateInterval('P15D')); var_dump($releaseDate < $buildDate); //bool(true)
Edit
As of the release of PHP 7.1 the results are different than with PHP 5.x, due to the added support for microseconds.
Example: https://3v4l.org/rCigC
$a = new \DateTime; $b = new \DateTime; var_dump($a < $b);
Results (7.1+):
bool(true)
Results (5.x - 7.0.x, 7.1.3):
bool(false)
To circumvent this behavior, it is recommended that you use clone
to compare the DateTime
objects instead.
Example: https://3v4l.org/CSpV8
$a = new \DateTime; $b = clone $a; var_dump($a < $b);
Results (5.x - 7.x):
bool(false)
Looks like there was a related bug/feature request, not sure if that ever made it in the trunk. It's not documented (that I Can find) either way - so probably not safe to use.
That said, after some testing it seems that they can be compared, but only after they've been 'evaluated' in some way (doing a var dump changes the outcome). Here's my test/result:
<?php $int15 = new DateInterval('P15D'); $int20 = new DateInterval('P20D'); var_dump($int15 > $int20); //should be false; var_dump($int20 > $int15); //should be true; var_dump($int15 < $int20); //should be true; var_dump($int20 < $int15); //should be false; var_dump($int15); var_dump($int20); var_dump($int15 > $int20); //should be false; var_dump($int20 > $int15); //should be true; var_dump($int15 < $int20); //should be true; var_dump($int20 < $int15); //should be false; $date = new DateTime(); $diff = $date->diff(new DateTime("+10 days")); var_dump($int15 < $diff); //should be false; var_dump($diff < $int15); //should be true; var_dump($int15 > $diff); //should be true; var_dump($diff > $int15); //should be false; var_dump($diff); var_dump($int15 < $diff); //should be false; var_dump($diff < $int15); //should be true; var_dump($int15 > $diff); //should be true; var_dump($diff > $int15); //should be false;
Result (I've omitted the full dumps of the interval objects):
bool(false) bool(false) bool(false) bool(false) object(DateInterval)#1 (8) {...} object(DateInterval)#2 (8) {...} bool(false) bool(true) bool(true) bool(false) bool(false) bool(true) bool(true) bool(false) object(DateInterval)#5 (8) {...} bool(false) bool(true) bool(true) bool(false)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With