tags:

views:

868

answers:

5

I'm trying to do some very basic time math - basically, given inputs of time and distance, calculate the speed. I chose to use strtotime() to convert the time inputs into seconds - but I'm getting some bizarre results.

For example, given this sample program:

<?php
$t1 = strtotime("3:15:00",0);
$t2 = strtotime("1:00:00",0);
$t3 = strtotime("2:00:00",0);
$t4 = strtotime("9:00:00",0);

echo $t1 . "\n";
echo $t2 . "\n";
echo $t3 . "\n";
echo $t4 . "\n";
?>

Why do I get these results?

$ php test.php 
-56700
-64800
-61200
-36000

Update:

Since no one said it explicitly, let me explain the bug in the above function. I had assumed that passing a time of zero to strtotime() would cause it to generate time stamps derived from midnight, 12/31/1969, UTC - which sounds odd, but would work for my purposes.

What I hadn't counted on was that strtotime() takes time zones into account when converting strings, and my server is apparently 5 hours behind UTC. On top of that, because of the time zone shift, PHP then interprets the times as relative to the day before the epoch which means it is interpreting my times as occurring relative to December 30th, 1969 instead of the 31st, resulting in negative numbers...

It appears that Eugene is correct - if I want to calculate just the elapsed time, I can't use the built in time functions.

+1  A: 

Apparently with just bare times PHP is assigning the date December 31, 1969. When I ran this:

echo date('F j, Y H:i:s', $t1) . "\n";
echo date('F j, Y H:i:s', $t2) . "\n";
echo date('F j, Y H:i:s', $t3) . "\n";
echo date('F j, Y H:i:s', $t4) . "\n";

I got this:

December 31, 1969 03:15:00
December 31, 1969 01:00:00
December 31, 1969 02:00:00
December 31, 1969 09:00:00

Remember that strtotime returns a UNIX timestamp, which is defined as the number of seconds since January 1, 1970. By definition a UNIX timestamp refers to a specific month/day/year, so despite the name strtotime is not really intended for bare times without dates.

John Kugelman
Then how do I convert bare times into elapsed seconds?
Mike Heinz
A: 

Try it without the second parameter. That's supposed to be a timestamp for the returned time to be relative to. Giving it 0 means you're asking for a timestamp relative to the Unix epoch.

In response to your comment:

It's not documented functionality, but I use strtotime("HH:MM") all the time, and it returns a timestamp relative to the current time. I guess if you want to be sure though, you could do this:

strtotime("3:15:00",time());
Andrew
Wouldn't that give me the number of seconds since 1969 to the current day, plus the provided time?All I want is to convert the provided time into seconds.
Mike Heinz
I've updated my answer to address your comment.
Andrew
That still gives me time relative to the epoch instead of just converting the string to seconds.
Mike Heinz
Remember - the original point was to take user-input distance and elapsed time and calculate the speed. The time isn't a time of day.
Mike Heinz
+4  A: 

If you want to do something like that, I think you want to just do some math on the time strings themselves and convert them to a number of seconds, like this:

<?php
function hmstotime($hms)
{
    list($hours, $minutes, $seconds) = explode(":",$hms);
    return $hours * 60 * 60 + $minutes * 60 + $seconds;
}
?>
Eugene Bulkin
Looking at the other answers, that might be the only approach.
Mike Heinz
Considering what you're doing this is probably the thing you're looking for (calculating speed and stuff like that). strtotime would require a little more complicated work to do what you want it to do, if it is possible - I haven't tried.
Eugene Bulkin
+1  A: 

Because strtotime() outputs the number of seconds relative to the second argument (in your case, the Unix epoch (December 31, 1969 19:00:00)).

The negative numbers is expected because "3:15:00" is 56700 seconds before the Unix epoch.

Adrian
How can a positive time occur before the epoch began? Is this a time zone thing?
Mike Heinz
A: 

strtotime() without a second argument gets the time from the supplied string and fills in the blanks from the current date:

echo date('Y-m-d H:i:s', strtotime("3:15:00"));
-> 2009-06-30 03:15:00

With a second argument it calculates the date relative to the second argument:

echo date('Y-m-d H:i:s', strtotime("3:15:00", 0));
-> 1970-01-01 03:15:00

To calculate the difference between two timestamps in seconds, you can just do this:

echo strtotime("3:15:00") - strtotime("3:00:00");
-> 900

Edit: Of course taking into account which is the bigger number:

$t1 = strtotime("3:15:00");
$t2 = strtotime("3:30:00");

$diff = max($t1, $t2) - min($t1, $t2);
$diff = abs($t1 - $t2);

Or something of that nature...

deceze