2

I'm getting aggregate values of time passed from DB in formats such as

 "84:00:00"
 "14:30:00"
 "20:00:00"
 "02:00:00"
"120:00:00"

and I need to convert that to integer values as follows:

 84
 14.5
 20
  2
120

is there any way to achieve this (rather simply); to my understanding strtotime() returns false if the value is greater than 24:00:00

toddddos
  • 321
  • 2
  • 11
  • `list($hours, $minutes, $seconds) = explode(':', $time);`, then a bit of math involving division by `60`… – deceze Jan 15 '18 at 14:59
  • PHP's time functions won't help you much, since you're dealing with *durations*, not timestamps. – deceze Jan 15 '18 at 15:00
  • @deceze Huh, that was easy.. all I had to do was `list($hours) = explode(':', $time);` and `return (int) $hours;` and what I got was the number of hours (why would I need to divide that further as you suggested?), thanks! – toddddos Jan 15 '18 at 15:06
  • Damn.. I need to add those minutes, I see now – toddddos Jan 15 '18 at 15:07
  • Please post solution as an answer not as an edit to question, see [tour] to learn more. – Petter Friberg Jan 15 '18 at 15:30

3 Answers3

1

Solution (thanks to @deceze):

if($time != '0') {
    list($hours, $minutes) = explode(':', $time);
    return $hours + ($minutes / 60);
}
return 0;
toddddos
  • 321
  • 2
  • 11
  • 1
    If you have durations that have seconds != 0, this will return invalid number of hours > https://eval.in/935575. You could also add seconds part > https://eval.in/935577 – Glavić Jan 16 '18 at 14:34
1

You could use the function TimeToSec() and then just devide seconds with 3600, and you will receive number of hours.

function TimeToSec($time) {
    $sec = 0;
    foreach (array_reverse(explode(':', $time)) as $k => $v) $sec += pow(60, $k) * $v;
    return $sec;
}

echo TimeToSec('14:30:00') / 3600;

demo

Glavić
  • 42,781
  • 13
  • 77
  • 107
-2

PHP's time functions won't help you much, since you're dealing with durations, not timestamps

@deceze, you are wrong:

foreach (['84:00:00', '14:30:00', '20:00:00', '02:00:00', '120:00:00'] as $time)
{
    list($h, $m, $s) = explode(':', $time);

    $diff = mktime($h, $m, $s) - mktime(0, 0, 0);

    print_r($diff / 60 / 60);
}
user1597430
  • 1,138
  • 1
  • 7
  • 14
  • Well, okay, you can abuse some time functions for this purpose if you know exactly how they'll work, but particularly in this case that's really the more complex solution. FWIW, there's the `DateInterval` class to represent actual durations. – deceze Jan 15 '18 at 16:01
  • BTW, `- mktime(0, 0, 0)` does absolutely nothing. ;) – deceze Jan 16 '18 at 07:02
  • @deceze, are you sure that you are PHP programmer? You are wrong everywhere. I believe you have to remove your "full stack" joke from your profile. – user1597430 Jan 16 '18 at 12:05
  • Gosh darn it, you're right, I was thinking of the missing parameters defaulting to January 1st 1970, in which case it would do nothing. This is simply not an approach I'd ever consider, so… And actually, if you're going to use it this way, I'd default those parameters to Jan. 1st 1970. It seems insane to use the current day as basis for calculations, and this approach is prone to the Y2K38 problem. – deceze Jan 16 '18 at 12:51
  • And since this kept bugging me, here's the worst bug: it's sensitive to timezones and thereby to DST changes and will produce incorrect results if run in a timezone with DST changes at the DST switchover time: https://3v4l.org/4ohr1 – Repeat after me: time functions are not for handling durations! – deceze Jan 17 '18 at 08:34
  • Pimple on the butt. Open man page about `mktime` and find `gmmktime` alias for timezone-sensitive scenario. Your attempts to ignore the truth are pathetic and look unmature. – user1597430 Jan 17 '18 at 11:22
  • Sure, there are ways you can fix this. But this code as is conditionally fails. Simple math wouldn't. – deceze Jan 17 '18 at 11:27