Viewed   101 times

What is the best way to calculate the total number of seconds between two dates? So far, I've tried something along the lines of:

$delta   = $date->diff(new DateTime('now'));
$seconds = $delta->days * 60 * 60 * 24;

However, the days property of the DateInterval object seems to be broken in the current PHP5.3 build (at least on Windows, it always returns the same 6015 value). I also attempted to do it in a way which would fail to preserve number of days in each month (rounds to 30), leap years, etc:

$seconds = ($delta->s)
         + ($delta->i * 60)
         + ($delta->h * 60 * 60)
         + ($delta->d * 60 * 60 * 24)
         + ($delta->m * 60 * 60 * 24 * 30)
         + ($delta->y * 60 * 60 * 24 * 365);

But I'm really not happy with using this half-assed solution.

 Answers

4

Could you not compare the time stamps instead?

$now = new DateTime('now');
$diff = $date->getTimestamp() - $now->getTimestamp()
Tuesday, December 20, 2022
1
function average_time($total, $count, $rounding = 0) {
    $total = explode(":", strval($total));
    if (count($total) !== 3) return false;
    $sum = $total[0]*60*60 + $total[1]*60 + $total[2];
    $average = $sum/(float)$count;
    $hours = floor($average/3600);
    $minutes = floor(fmod($average,3600)/60);
    $seconds = number_format(fmod(fmod($average,3600),60),(int)$rounding);
    return $hours.":".$minutes.":".$seconds;
}
echo average_time("2452:43:44", 15); // prints "163:30:55"
echo average_time("2452:43:44", 15, 2); // prints "163:30:54.93"
Wednesday, August 3, 2022
 
5

As far as I'm aware, there's no guaranteed way of working backwards. The best way might be to try to match regular expressions against expected well-known formats (e.g. d{2,4}[-/]d{2}[-/]d{2} for "Y-m-d") but I can't think of an easy way to do the matching without using regular expressions. You would also have to check that the parsed format makes sense, and you can't do much about ambiguous dates like 2nd of March 2009, which could be represented as 09/03/02, 2009-03-02, 02/03/09, 03/02/09, or even 09/02/03.

Sunday, December 25, 2022
1

There is a function format for this. But it wont return the number of seconds. To get number of seconds you use this technique

$seconds = abs($datetime1->getTimestamp()-$datetime2->getTimestamp());

If you really want to use $interval you need to calculate it.

$seconds = $interval->days*86400 + $interval->h*3600 
           + $interval->i*60 + $interval->s;

Here

  • 86400 is the number of seconds in a day
  • 3600 is the number of seconds in an hour
  • 60 is the number of seconds in a minute
Wednesday, November 30, 2022
1

Why it's not a bug:

The current behavior is correct. The following happens internally:

  1. +1 month increases the month number (originally 1) by one. This makes the date 2010-02-31.

  2. The second month (February) only has 28 days in 2010, so PHP auto-corrects this by just continuing to count days from February 1st. You then end up at March 3rd.

How to get what you want:

To get what you want is by: manually checking the next month. Then add the number of days next month has.

I hope you can yourself code this. I am just giving what-to-do.

PHP 5.3 way:

To obtain the correct behavior, you can use one of the PHP 5.3's new functionality that introduces the relative time stanza first day of. This stanza can be used in combination with next month, fifth month or +8 months to go to the first day of the specified month. Instead of +1 month from what you're doing, you can use this code to get the first day of next month like this:

<?php
$d = new DateTime( '2010-01-31' );
$d->modify( 'first day of next month' );
echo $d->format( 'F' ), "n";
?>

This script will correctly output February. The following things happen when PHP processes this first day of next month stanza:

  1. next month increases the month number (originally 1) by one. This makes the date 2010-02-31.

  2. first day of sets the day number to 1, resulting in the date 2010-02-01.

Tuesday, October 25, 2022
 
carol
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :