Are PHP DateInterval comparable like DateTime?

artragis picture artragis · Mar 3, 2012 · Viewed 18.2k times · Source

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.

Answer

Will B. picture Will B. · Feb 24, 2015

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)