Converting To And From Decimal Time In PHP

To convert a time value into a decimal value representing the number of minutes can be useful for certain calculations. The following function takes a time as a string of hh:mm:ss and returns a decimal value in minutes.

/**
 * Convert time into decimal time.
 *
 * @param string $time The time to convert
 *
 * @return integer The time as a decimal value.
 */
function time_to_decimal($time) {
    $timeArr = explode(':', $time);
    $decTime = ($timeArr[0]*60) + ($timeArr[1]) + ($timeArr[2]/60);

    return $decTime;
}

If we take the time of 11:11:11 this gets split into 3 parts by the explode() function into hours, minutes and seconds, which then gets treated in the following way:

Minutes = (Hours x 60) + (Minutes) + (Seconds / 60)
Minutes = (11 x 60) + (11) + (11 / 60)
Minutes = (660) + (11) + (0.18333333)
Minutes = 671.18333333

The function can be used as follows:

echo time_to_decimal("11:11:11"); // prints 671.18333333

The reverse of this function takes the decimal value and returns a string in the format hh:mm:ss.

/**
 * Convert decimal time into time in the format hh:mm:ss
 *
 * @param integer The time as a decimal value.
 *
 * @return string $time The converted time value.
 */
function decimal_to_time($decimal) {
    $hours = floor($decimal / 60);
    $minutes = floor($decimal % 60);
    $seconds = $decimal - (int)$decimal;
    $seconds = round($seconds * 60);

    return str_pad($hours, 2, "0", STR_PAD_LEFT) . ":" . str_pad($minutes, 2, "0", STR_PAD_LEFT) . ":" . str_pad($seconds, 2, "0", STR_PAD_LEFT);
}

This function can be used as follows:

echo decimal_to_time(671.18333333); // prints 11:11:11

Note that these functions deal with amounts of time, not the time of day. Converting between time and decimal time of day requires a different set of calculations.

UPDATE: Thanks to an anonymous poster for pointing out some errors, these have now been corrected.

Comments

Hi Philip,

Your code indeed works in the manner you have described, however there are a couple of finer details that caused issues for me when using the code.

In the time_to_decimal function, line 12 should read as follows:

$decTime = ($timeArr[0]*60) + ($timeArr[1]) + ($timeArr[2]/60);

As it is written in your post, the seconds are actually representing fractions of an hour (1/3600th) as opposed to fractions of a minute (1/60th). 

We have the same issue in the decimal_to_time function as well as an issue in regards to the round() function.  I've corrected the decimal_to_time function as follows:

function decimal_to_time($decimal) {
    $hours = floor((int)$decimal / 60);
    $minutes = floor((int)$decimal % 60);
    $seconds = $decimal - (int)$decimal; 
    $seconds = round($seconds * 60); 
 
    return str_pad($hours, 2, "0", STR_PAD_LEFT) . ":" . str_pad($minutes, 2, "0", STR_PAD_LEFT) . ":" . str_pad($seconds, 2, "0", STR_PAD_LEFT);
}

round() in lines 2 and 3 have been replaced by floor().  This is due to the behavior of round() returning 1 when given .5.  An example is as follows:

Say we are converting 1:30:30 into a decimal representing minutes.  Using the two functions posted we would have

echo time_to_decimal('1:30:30'); // prints 90.008333333333, seconds are still converted incorrectly

// this should display the input from the first function
echo decimal_to_time(90.008333333333); // prints 02:02:30, not correct

In the example, line 2 of the original code calculates to - round( 90 / 60 ) = round(1.5) = 2.  Since we only want the numer of whole hours in the $decimal variable, we should use floor() instead.  floor() will always round to the lowest whole number ( 1 in this case )

I hope this helps someone out there :)

Permalink

Thank you for all the hard work you put into that comment! I really appreciate it when a user posts such detailed comments on this blog :)

I have tested your examples and updated my code accordingly.

Name
Philip Norton
Permalink

hi tae, thanks..

Permalink

i propose to change little to allow this kind of input "01:05" =1h05 or "01:05:00" or "01"=1hour

function time_to_decimal($time) {
  $timeArr = explode(':', $time);
  if (count($timeArr) == 3) {
    $decTime = ($timeArr[0]*60) + ($timeArr[1]) + ($timeArr[2]/60);
  } else if (count($timeArr) == 2) {
    $decTime = ($timeArr[0]) + ($timeArr[1]/60);
  } else if (count($timeArr) == 2) {
    $decTime = $time;
  }
  return $decTime;
}

 

Permalink

This function kept returning :60 in the seconds place! I added :

if ($seconds == 60) {
   $minutes++; $seconds=0;
}

to the end of the function.

Permalink

My 2 cents comment if used your function and added a format control to avoid strange behavior and surprise

function Time_To_Decimal($time) {
  $decTime = 0;
  if (preg_match("/^([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/", $time, $matches)) {
    $decTime = ($matches[0]*60) + ($matches[1]) + ($matches[2]/60);
  }
  return $decTime;
}

Thanks a lot for posting

Permalink

Sorry posted too quickly (fixed preg_match return array)

function Time_To_Decimal($time) {
  $decTime = 0;
  if (preg_match("/^([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/", $time, $matches)) {
    $decTime = ($matches[1]*60) + ($matches[2]) + ($matches[3]/60);
  }
  return $decTime;
}
Permalink
gmmktime() -> time 2 decimal
Permalink

Error here

floor($decimal % 60);

and not

floor($decimal % / 60);

 

Permalink

Quite right Gianluca, thanks for pointing that out.

Name
Philip Norton
Permalink

Add new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
8 + 3 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.