Are PHP Dateinterval Comparable Like Datetime

Are PHP DateInterval comparable like DateTime?

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)

PHP DateTime formatting works but DateInterval formatting not working

First of all, it works completely differently to your explanation. In order to check you may place a debug statement to output the type of object:

echo 'Type: ', get_class($duration), '<br>';

echo $duration->format('%H:%I');
echo '<br>';
echo $row['2'];

So code in if-block returns DateTime while code in else-block returns DateInterval.

The reason why you have the issue is simply that DateTime and DateInterval have different format types, DateInterval indeed requires to escape with a %-sign all the formatting symbols while DateTime uses the same format styles as date function.

I see two ways to fix an issue: easy one is just to introduce one more variable which stores a necessary format and set it to a corresponding value in if and else blocks, another way - rewrite you code to make $duration variable have the same type in both cases.

PHP DateInterval create split second (microsecond or milisecond) interval

There is a way to do this using DateInterval::createFromDateString:

$di = DateInterval::createFromDateString('123456 microseconds');
var_dump($di);

Output:

object(DateInterval)#1 (16) {
["y"]=>
int(0)
["m"]=>
int(0)
["d"]=>
int(0)
["h"]=>
int(0)
["i"]=>
int(0)
["s"]=>
int(0)
["f"]=>
float(0.123456)
["weekday"]=>
int(0)
["weekday_behavior"]=>
int(0)
["first_last_day_of"]=>
int(0)
["invert"]=>
int(0)
["days"]=>
bool(false)
["special_type"]=>
int(0)
["special_amount"]=>
int(0)
["have_weekday_relative"]=>
int(0)
["have_special_relative"]=>
int(0)
}

Demo on 3v4l.org

From the manual:

time

A date with relative parts. Specifically, the relative formats supported by the parser used for strtotime() and DateTime will be used to construct the DateInterval.

DateInterval - Difference between two times

You can calculate diif of (any time + interval1) and (the same time + interval2)

$estimate = new DateInterval('PT6H8M');
$total_time = new DateInterval('PT5H7M');
$time = new DateTime('midnight');
$time->add($total_time);
$time1 = new DateTime('midnight');
$diff = $time1->add($estimate)->diff($time);
var_dump($diff); // object(DateInterval) ... ["h"]=> int(1) ["i"]=> int(1) ...

Wrong DateInterval with DateTime diff

The problem is that when you assign an object to a variable, it is assigned by reference. So when you do:

$date_past = $date_now->sub(new DateInterval("PT12H"));

The variables $date_past and $date_now both point to exactly the same reference and when you modify one, you modify both. You will notice this if you simply echo out the variables:

$date_now = new DateTime;
$date_past = $date_now->sub(new DateInterval("PT12H"));

echo $date_now->format('c'); // 2014-03-10T00:38:56-06:00
echo $date_past->format('c'); // 2014-03-10T00:38:56-06:00

Notice how they both print exactly the same thing. Normally what you want to do is use clone:

$date_past = clone $date_now;
$date_past->sub(new DateInterval("PT12H"));

echo $date_now->format('c'); // 2014-03-10T12:41:20-06:00
echo $date_past->format('c'); // 2014-03-10T00:41:20-06:00

PHP: Datetime::Diff results comparison

It seems that DateInterval doesn't implement a comparison function internally. Extensions are allowed to define custom comparison rules for their predefined classes. Evidently it falls back to a loose comparison that the objects are of the same class.

This feature request provides a patch to add this functionality in, but it doesn't seem to have made it into the source at any point.

To get around this issue, you can either compare each member variable of your objects yourself (years, months etc.) or you can cast each object to an array:

if ((array) $interval == (array) $interval2) {
echo 'true';
} else {
echo 'false';
}

What is the difference between the days and d property in DateInterval

  • d - the days from the start of the month that need to be added after the months are added - (Feb 23 - Jan 1).d == 22)
  • days - the total number of days - (Feb 23 - Jan 1).days == 31 + 22)

From the documentation:

d

Number of days.

days

If the DateInterval object was created by DateTime::diff(), then this is the total number of days between the start and end dates.
Otherwise, days will be FALSE.

Before PHP 5.4.20/5.5.4 instead of FALSE you will receive -99999 upon
accessing the property.



Related Topics



Leave a reply



Submit