EDIT:

class ComparableDateInterval extends DateInterval { /** * Leap-year safe comparison of DateInterval objects. */ public function compare(DateInterval $oDateInterval) { $fakeStartDate1 = date_create(); $fakeStartDate2 = clone $fakeStartDate1; $fakeEndDate1 = $fakeStartDate1->add($this); $fakeEndDate2 = $fakeStartDate2->add($oDateInterval); if($fakeEndDate1 < $fakeEndDate2) { return -1; } elseif($fakeEndDate1 == $fakeEndDate2) { return 0; } return 1; } } $int15 = new ComparableDateInterval('P15D'); $int20 = new ComparableDateInterval('P20D'); var_dump($int15->compare($int20) == -1); // should be true;

See @fyrye's answer for the rationale (and upvote it!). My original answer did not deal with leap years safely.

Original Answer

While I upvoted this question, I downvoted the accepted answer. That's because it didn't work for me on any of my PHP installations and because fundamentally it's hinging on something broken internally.

What I did instead is migrate the aforementioned patch which never made it into trunk. FWIW I checked a recent release, PHP 5.6.5, and the patch still isn't there. The code was trivial to port. The only thing is a warning in how it makes the comparison

If $this->days has been calculated, we know it's accurate, so we'll use that. If not, we need to make an assumption about month and year length, which isn't necessarily a good idea. I've defined months as 30 days and years as 365 days completely out of thin air, since I don't have the ISO 8601 spec available to check if there's a standard assumption, but we may in fact want to error out if we don't have $this->days available.

Here's an example. Note, if you need to compare a DateInterval that was returned from some other call, you'll have to create a ComparableDateInterval from it first, if you want to use it as the source of the comparison.

$int15 = new ComparableDateInterval('P15D'); $int20 = new ComparableDateInterval('P20D'); var_dump($int15->compare($int20) == -1); // should be true;

Here's the code