45

Hi All I'm trying to calculate elapsed time in php. The problem is not in php, it's with my mathematical skills. For instance: Time In: 11:35:20 (hh:mm:ss), now say the current time is: 12:00:45 (hh:mm:ss) then the time difference in my formula gives the output: 1:-34:25. It should actually be: 25:25

$d1=getdate();
$hournew=$d1['hours'];
$minnew=$d1['minutes'];
$secnew=$d1['seconds'];

$hourin = $_SESSION['h'];
$secin = $_SESSION['s'];
$minin = $_SESSION['m'];

$h1=$hournew-$hourin;
$s1=$secnew-$secin;
$m1=$minnew-$minin;

if($s1<0) {
    $s1+=60; }
if($s1>=(60-$secin)) {
    $m1--;  }
if($m1<0) {
    $m1++; }
echo $h1 . ":" . $m1 . ":" . $s1;

Any help please?

EDIT

Sorry I probably had to add that the page refreshes every second to display the new elapsed time so I have to use my method above. My apologies for not explaining correctly.

Wilest
  • 1,820
  • 7
  • 36
  • 62
  • Consider converting to timestamps with `mktime()` and then do simple subtraction. And maybe it would be a good idea to simply work with `time()` instead of `getdate()` in that case. – Till Helge Oct 21 '11 at 13:47
  • and if you were using an inverse approach? You know the time in which the user logged in and then on display a kind of trial? – JellyBelly Oct 21 '11 at 13:48
  • Than you all for the responses, I finally got it working after looking at all the answers with the following: ` if($s1<0) { $s1+=60; } if($s1>=(60-$secin)) { $m1--; } if($m1<0) { $m1 *= -1; $m1 = (60 - $m1); $h1--; } ` – Wilest Oct 21 '11 at 14:41

5 Answers5

81

This will give you the number of seconds between start and end.

<?php

// microtime(true) returns the unix timestamp plus milliseconds as a float
$starttime = microtime(true);
/* do stuff here */
$endtime = microtime(true);
$timediff = $endtime - $starttime;

?>

To display it clock-style afterwards, you'd do something like this:

<?php

// pass in the number of seconds elapsed to get hours:minutes:seconds returned
function secondsToTime($s)
{
    $h = floor($s / 3600);
    $s -= $h * 3600;
    $m = floor($s / 60);
    $s -= $m * 60;
    return $h.':'.sprintf('%02d', $m).':'.sprintf('%02d', $s);
}

?>

If you don't want to display the numbers after the decimal, just add round($s); to the beginning of the secondsToTime() function.

WWW
  • 9,734
  • 1
  • 29
  • 33
  • You did not read the question properly. He doesn't want to measure the runtime of his script, but rather an arbitrary timespan. – Till Helge Oct 21 '11 at 13:45
  • I aknowledge it might be misleading, but imho he's not asking for benchmarking, but for calculating a simple time difference. Think at, let's say, a travel duration, or a race, or something like that – Damien Pirsy Oct 21 '11 at 13:45
  • Sorry I probably had to add that the page refreshes every second to display the new elapsed time so I have to use my method above. My apologies for not explaining correctly. – Wilest Oct 21 '11 at 13:48
  • 2
    That would change my answer a little bit, though the other recommendations would back up the idea of storing the times you'd like to compare as either DateTime objects or as UNIX timestamps. Do all your work in the same unit (in this case seconds) and then convert back to a more display-friendly time. – WWW Oct 21 '11 at 13:56
  • I would recommend using a nicer modulo block, One posted on php's manual is the one I prefer to copy: http://php.net/manual/en/function.time.php#108581 – ThorSummoner Aug 13 '14 at 18:10
  • @ThorSummoner The main reason I left it the way it is was to illustrate the thought process of how the reduction process happens. I agree that modulo tricks are probably faster. – WWW Oct 16 '14 at 17:38
34

Using PHP >= 5.3 you could use DateTime and its method DateTime::diff(), which returns a DateInterval object:

$first  = new DateTime( '11:35:20' );
$second = new DateTime( '12:00:45' );

$diff = $first->diff( $second );

echo $diff->format( '%H:%I:%S' ); // -> 00:25:25
Decent Dabbler
  • 22,532
  • 8
  • 74
  • 106
7

Keep track of your time using the 'time()' function. You can later convert 'time()' to other formats.

$_SESSION['start_time'] = time();

$end_time = time();

$end_time - $_SESSION['start_time'] = 65 seconds (divide by 60 to get minutes)

And then you can compare that to another value later on.

Use microtime if you need millisecond detail.

donutdan4114
  • 1,262
  • 1
  • 8
  • 16
0

For high resolution time, try using monotonic clock: hrtime

<?php
$time = -hrtime(true);
sleep(5);
$end = sprintf('%f', $time += hrtime(true));
?>

Difference between CLOCK_REALTIME and CLOCK_MONOTONIC?

呂學洲
  • 1,123
  • 8
  • 19
0

You can implement the solutions shown, but I'm fond of using the phptimer class (or others, this wheel has been invented a few times). The advantage is that you can usually define the timer to be active or not, thereby permitting you to leave the timer calls in your code for later reference without re-keying all the time points.

Duane Gran
  • 490
  • 4
  • 9