Kevin Marshall
Kevin Marshall

Reputation: 47

PHP DateTime formatting works but DateInterval formatting not working

I've got a bit of PHP code here that calculates (and echos out) a time duration. I have an if/else that chooses how to calculate the duration. Due to the way i have done the calculations, under one circumstance the duration that is output is a DateTime object, under the other it is a DateInterval object. The formatting of both is done outside the if/else statement.

The calculations are working fine, and the formatting for the DateTime object are working fine, but the formatting for the DateInterval object is off. It shows percent signs within the output time (example at the end of the codeblock).

$time1 = new DateTime($row[0]); 
$time2 = new DateTime($row[1]);

if ($time1 > $time2) { 
    $twentyFourHours = new DateTime('240000');
    $difference = $time1->diff($twentyFourHours);
    $time2->add($difference);
    $duration = $time2; // this is a DateInterval object
}

else    {
$duration = $time2->diff($time1);  // This is a DateTime object
        }  

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

Below is an example of the output i am getting (every other duration is the DateInterval object with the percent signs):

02:10
2016-06-16

%12:%0
2016-06-16

03:04
2016-06-17

%12:%0
2016-06-17

From what i can tell in the DateInterval formatting docs, i am setting the formatting correctly for two digit hours and two digit minutes ('%H:%I'), but the output would seem to prove otherwise. I am guessing i am overlooking something silly and would be grateful if someone could point out where i am going wrong.

Many Thanks!

Upvotes: 2

Views: 1472

Answers (2)

Katie
Katie

Reputation: 2693

I put this in my debugger and set it up so that $time1 was greater than $time2 by 2 hours and 10 minutes, which looked like your first data set and got the same error.

When watching it in the debugger, $duration was a DateTime object instead of a Duration object. Specifically:

$duration = $time2; // this is a DateInterval object

$time2 is a DateTime object, so $duration became a DateTime object and hence the format fails.

So, in your code:

   // find the duration since midnight
   $twentyFourHours = new DateTime('240000');
   $difference = $time1->diff($twentyFourHours);

   // add that difference to time2...hmmm
   $time2->add($difference);

   // copy time2 to duration, this will copy the $time2 DateTime object
   $duration = $time2; // this is a DateInterval object

It looks like you are getting the time duration since midnight for $time1, and then adding it to $time2, I am wondering if that is where the typo is, where you meant to do something else? Hope that helps!

Upvotes: 2

ConstantineUA
ConstantineUA

Reputation: 1051

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.

Upvotes: 1

Related Questions