PHP Function to Format an Integer as HH:MM:SS

Here's a function (plus two shortcut functions) that will let you format an integer as HH:MM:SS format using PHP. All you have to do is input the number of seconds and/or minutes and/or hours (it accepts decimal values for any of these), specify the precision you'd like to use, and go. You can also use this function to get from hours to minutes and seconds, or the other way around.

The logic behind the function is a little trickier than you'd imagine because of the preceding zeroes. I wrote this for myself at least half a dozen times before finally realizing that I should make a function out of it and share with everyone else. If you have any suggestions or questions, please leave them in the comments below.

<?php

//the main (new) function
function hms($args=array()) {
	$defaults = array(
		'hours'=>0, //incoming hours
		'minutes'=>0, //incoming minutes
		'seconds'=>0, //incoming seconds
		'precision'=>0, //outgoing precision: "minutes" for minutes (no seconds) or an integer for precision of seconds
		'return'=>null, //what to return; if null, everything is returned in an array
	);
	foreach ($defaults as $key => $default) {
		if (array_key_exists($key,$args)) { $$key = $args[$key]; } else { $$key = $default; }
	}	

	$hours = abs($hours);
	$minutes = abs($minutes);
	$seconds = abs($seconds);
	$total_seconds = ($hours * 3600) + ($minutes * 60) + $seconds;
	unset($hours,$minutes,$seconds); //to prevent confusion

	if ($precision === 'minutes') { $total_seconds = round($total_seconds/60) * 60; }
	elseif ($precision === 0) { $total_seconds = round($total_seconds); }
	elseif ($precision !== false) { $total_seconds = round($total_seconds,$precision); }

	//calculate years, days, hours, minutes, seconds
	$remaining_seconds = $total_seconds;
	$years = floor($remaining_seconds / 31557600); //365.25 days
	$remaining_seconds = $remaining_seconds - ($years * 31557600);
	$days = floor($remaining_seconds / 86400);
	$remaining_seconds = $remaining_seconds - ($days * 86400);
	$hours = floor($remaining_seconds / 3600);
	$remaining_seconds = $remaining_seconds - ($hours * 3600);
	$minutes = floor($remaining_seconds / 60);
	$seconds = $remaining_seconds - ($minutes * 60);
	unset($remaining_seconds);

	//start return array (if we're returning an array)
	if (!$return) {
		$hms = array('total_seconds'=>$total_seconds,'years'=>$years,'days'=>$days,'hours'=>$hours,'minutes'=>$minutes,'seconds'=>$seconds);
	}

	//if text, and value is over 24 hours, switch to shorttext
	if (($return == 'text') && ($days > 0)) { $return = 'shorttext'; }

	//text (h:mm:ss)
	if ((!$return) || ($return == 'text')) {
		if ($hours > 0) {
			$hh = $hours;
			$text = $hours.':';
		} else {
			$hh = '';
			$text = '';
		}
		if (($minutes >= 10) || ($hours == 0)) { $mm = $minutes; }
		elseif ($hours > 0) { $mm = '0'.$minutes; }
		if (($minutes > 0) || ($hours > 0)) {
			$text .= $mm.':';
		} else {
			$mm = '';
		}
		if ((($minutes > 0) || ($hours > 0)) && ($seconds == 0)) { $ss = '00'; }
		elseif (($seconds >= 10) || ($minutes < 1)) { $ss = $seconds; }
		else { $ss = '0'.$seconds; }
		$text .= $ss;

		if ($return == 'text') { return $text; }
		else {
			$hms['text'] = $text;
			$hms['hh'] = $hh; //blank (instead of "0") if no hours
			$hms['mm'] = $mm; //includes preceding zero so hh:mm:ss looks right, blank if no hours and no minutes
			$hms['ss'] = $ss; //includes preceding zero so hh:mm:ss looks right
		}
	}

	//long text (comma separated numbers and words)
	if ((!$return) || ($return == 'longtext')) {
		$longtext = array();
		if ($years > 0) {
			if ($years > 1) { $longtext[] = number_format($years).' years'; }
			else { $longtext[] =  '1 year'; }
		}
		if ($days > 0) {
			if ($days > 1) { $longtext[] =  number_format($days).' days'; }
			else { $longtext[] =  '1 day'; }
		}
		if ($hours > 0) {
			if ($hours > 1) { $longtext[] =  number_format($hours).' hours'; }
			else { $longtext[] =  '1 hour'; }
		}
		if ($minutes > 0) {
			if ($minutes > 1) { $longtext[] =  $minutes.' minutes'; }
			else { $longtext[] =  '1 minute'; }
		}
		if (($seconds > 0) || (count($longtext) == 0)) {
			if ($seconds != 1) { $longtext[] =  $seconds.' seconds'; }
			else { $longtext[] =  '1 second'; }
		}		
		$longtext = implode(', ',$longtext);
		if ($return == 'longtext') { return $longtext; }
		else { $hms['longtext'] = $longtext; }
	}

	//short text (1 rounded number)
	if ((!$return) || ($return == 'shorttext')) {
		if ($years > 0) {
			$shorttext = round(($total_seconds/31557600),1);
			if ($shorttext == 1) { $shorttext .= ' year'; } else { $shorttext .= ' years'; }
		} elseif ($days > 0) {
			$shorttext = round(($total_seconds/86400),1);
			if ($shorttext == 1) { $shorttext .= ' day'; } else { $shorttext .= ' days'; }
		} elseif ($hours > 0) {
			$shorttext = round(($total_seconds/3600),1);
			if ($shorttext == 1) { $shorttext .= ' hour'; } else { $shorttext .= ' hours'; }
		} elseif ($minutes > 0) {
			$shorttext = round(($total_seconds/60),1);
			if ($shorttext == 1) { $shorttext .= ' minute'; } else { $shorttext .= ' minutes'; }
		} else {
			$shorttext = round($total_seconds,1);
			if ($shorttext == 1) { $shorttext .= ' second'; } else { $shorttext .= ' seconds'; }
		}
		if ($return == 'shorttext') { return $shorttext; }
		else { $hms['shorttext'] = $shorttext; }
	}

	return $hms;
}

//shortcut functions
function seconds_to_hms($seconds) {
	return hms(array('seconds'=>$seconds,'return'=>'text'));
}

function seconds_to_longtext($seconds) {
	return hms(array('seconds'=>$seconds,'return'=>'longtext'));
}

function seconds_to_shorttext($seconds) {
	return hms(array('seconds'=>$seconds,'return'=>'shorttext'));
}

//other functions
function hms_to_seconds($hours,$minutes,$seconds) {
	$seconds = ($hours * 3600) + ($minutes * 60) + $seconds;
	return $seconds;
}

function hms_string_to_seconds($string) {
	$string = trim($string);
	$p = explode(':',$string);
	if ((count($p) == 1) && (is_numeric($p['0']))) { $h = 0; $m = 0; $s = $p['0']; }
	elseif (count($p) == 2) { $h = 0; $m = $p['0']; $s = $p['1']; }
	elseif (count($p) == 3) { $h = $p['0']; $m = $p['1']; $s = $p['2']; }
	else { return false; } //could not recognize pattern
	return hms_to_seconds($h,$m,$s);
}

//the old function
//delete the commented out old function when possible... a legacy workaround is in place here:
function hms_conversion($hours,$minutes,$seconds,$precision=0,$include_seconds_in_longtext=true) {
	return hms(array('hours'=>$hours,'minutes'=>$minutes,'seconds'=>$seconds,'precision'=>$precision));
}
/*function hms_conversion($hours,$minutes,$seconds,$precision=0,$include_seconds_in_longtext=true) {
	$hours = abs($hours);
	$minutes = abs($minutes);
	$seconds = abs($seconds);
	$total_seconds = ($hours * 3600) + ($minutes * 60) + $seconds;
	if ($precision === 0) { $total_seconds = round($total_seconds); }
	elseif ($precision !== false) { $total_seconds = round($total_seconds,$precision); }

	//calculate years, days, hours, minutes, seconds
	$remaining_seconds = $total_seconds;

	$years = floor($remaining_seconds / 31557600); //365.25 days
	$remaining_seconds = $remaining_seconds - ($years * 31557600);
	
	$days = floor($remaining_seconds / 86400);
	$remaining_seconds = $remaining_seconds - ($days * 86400);

	$hours = floor($remaining_seconds / 3600);
	$remaining_seconds = $remaining_seconds - ($hours * 3600);

	$minutes = floor($remaining_seconds / 60);

	$seconds = $remaining_seconds - ($minutes * 60);

	unset($remaining_seconds);

	$hms = array('total_seconds'=>$total_seconds,'years'=>$years,'days'=>$days,'hours'=>$hours,'minutes'=>$minutes,'seconds'=>$seconds,'shorttext'=>null);

	//now, format text and longtext
	$text = '';
	$longtext = '';
	if ($years > 0) {
		if ($years > 1) { $longtext .= number_format($years).' years, '; }
		else { $longtext .= '1 year, '; }
		$hms['shorttext'] = round(($total_seconds/31557600),1).'';
		if ($hms['shorttext'] == 1) { $hms['shorttext'] .= ' year'; } else { $hms['shorttext'] .= ' years'; }
	}
	if ($days > 0) {
		if ($days > 1) { $longtext .= number_format($days).' days, '; }
		else { $longtext .= '1 day, '; }
		if (!$hms['shorttext']) {
			$hms['shorttext'] = round(($total_seconds/86400),1).'';
			if ($hms['shorttext'] == 1) { $hms['shorttext'] .= ' day'; } else { $hms['shorttext'] .= ' days'; }
		}
	}
	if ($hours > 0) {
		$hh = $hours;
		$text .= $hours.':';
		if ($hours > 1) { $longtext .= number_format($hours).' hours, '; }
		else { $longtext .= '1 hour, '; }
		if (!$hms['shorttext']) {
			$hms['shorttext'] = round(($total_seconds/3600),1).'';
			if ($hms['shorttext'] == 1) { $hms['shorttext'] .= ' hour'; } else { $hms['shorttext'] .= ' hours'; }
		}
	} else {
		$hh = '';
	}
	if (($minutes >= 10) || ($hours == 0)) { $mm = $minutes; }
	elseif ($hours > 0) { $mm = '0'.$minutes; }
	if (($minutes > 0) || ($hours > 0)) {
		$text .= $mm.':';
		if ($minutes != 1) { $longtext .= $minutes.' minutes, '; }
		else { $longtext .= '1 minute, '; }
	} else {
		$mm = '';
	}
	if (($minutes > 0) && (!$hms['shorttext'])) {
		$hms['shorttext'] = round(($total_seconds/60),1).'';
		if ($hms['shorttext'] == 1) { $hms['shorttext'] .= ' minute'; } else { $hms['shorttext'] .= ' minutes'; }
	}
	if (!$hms['shorttext']) {
		$hms['shorttext'] = round($total_seconds,1).'';
		if ($hms['shorttext'] == 1) { $hms['shorttext'] .= ' second'; } else { $hms['shorttext'] .= ' seconds'; }
	}
	if ((($minutes > 0) || ($hours > 0)) && ($seconds == 0)) { $ss = '00'; }
	elseif (($seconds >= 10) || ($seconds == $total_seconds)) { $ss = $seconds; }
	else { $ss = '0'.$seconds; }
	$text .= $ss;
	if ($include_seconds_in_longtext) {
		if ($seconds != 1) { $longtext .= $seconds.' seconds'; }
		else { $longtext .= '1 second'; }
	} else {
		if ($longtext) { $longtext = substr($longtext,0,-2); } //get rid of ", "
	}
	$hms['hh'] = $hh; //blank (instead of "0") if no hours
	$hms['mm'] = $mm; //includes preceding zero so hh:mm:ss looks right, blank if no hours and no minutes
	$hms['ss'] = $ss; //includes preceding zero so hh:mm:ss looks right
	if ($days > 0) { $hms['text'] = '> 24:00:00'; } //this isn't intended to be used this way
	else { $hms['text'] = $text; }
	$hms['longtext'] = $longtext;
	
	return $hms;
}*/

//the javascript dropdowns function
function js_hms_dropdowns($args=array()) {
	$defaults = array(
		'name'=>'hms',
		'value'=>0,
		'onchange'=>'',
		'class'=>false,
	);
	foreach ($defaults as $key => $default) {
		if (array_key_exists($key,$args)) { $$key = $args[$key]; } else { $$key = $default; }
	}
	//echo '<pre>'.print_r($args,true).'</pre>';

	$s = '<input type="hidden" id="'.$name.'" value="'.$value.'">';

	$onchange = trim('update_hms_'.$name.'(); '.$onchange);

	$remaining = $value;
	$hours = floor($remaining / 3600);
	$remaining = $remaining - (3600 * $hours);
	$minutes = floor($remaining / 60);
	$remaining = $remaining - (60 * $minutes);
	$seconds = round($remaining);

	if ($class) { $class = ' class="'.$class.'"'; } else { $class = ''; }

	//hours
	$s .= '<select id="'.$name.'_hours"'.$class.' onchange="'.$onchange.'">';
	for ($i=0;$i<=48;$i++) {
		if ($i == $hours) { $selected = ' selected'; } else { $selected = ''; }
		$s .= '<option value="'.$i.'"'.$selected.'>'.$i.'</option> ';
	}
	$s .= '</select> ';

	//minutes
	$s .= '<select id="'.$name.'_minutes"'.$class.' onchange="'.$onchange.'">';
	for ($i=0;$i<60;$i++) {
		if ($i < 10) { $ii = '0'.$i; } else { $ii = $i; }
		if ($i == $minutes) { $selected = ' selected'; } else { $selected = ''; }
		$s .= '<option value="'.$i.'"'.$selected.'>'.$ii.'</option> ';
	}
	$s .= '</select> ';

	//seconds
	$s .= '<select id="'.$name.'_seconds"'.$class.' onchange="'.$onchange.'">';
	for ($i=0;$i<60;$i++) {
		if ($i < 10) { $ii = '0'.$i; } else { $ii = $i; }
		if ($i == $seconds) { $selected = ' selected'; } else { $selected = ''; }
		$s .= '<option value="'.$i.'"'.$selected.'>'.$ii.'</option> ';
	}
	$s .= '</select>';

	$s .= '<script>';
	$s .= 'function update_hms_'.$name.'() {';
		$s .= 'var seconds = (Math.round(document.getElementById(\''.$name.'_hours\').value) * 3600)';
		$s .= ' + (Math.round(document.getElementById(\''.$name.'_minutes\').value) * 60)';
		$s .= ' + Math.round(document.getElementById(\''.$name.'_seconds\').value);';
		$s .= 'document.getElementById(\''.$name.'\').value = seconds;';
	$s .= '}';
	$s .= '</script>';

	return $s;
}

?>

So you can see how it works, I've included a few examples below:

$hms = hms_conversion(0,0,5400.5,0);
echo $hms['longtext']; //returns 1 hour, 30 minutes, 1 second

$hms = hms_conversion(0,0,5400.5,0);
echo $hms['text']; //returns 1:30:01

$hms = hms_conversion(2,0,5400.5,false);
echo $hms['text']; //returns 3:30:00.5

$hms = hms_conversion(2.5,0,0,1);
echo $hms['text']; //returns 2:30:00

$hms = hms_conversion(2.5,0,0,0);
echo $hms['total_seconds']; //returns 9000

$hms = hms_conversion(0,20.43,0,2);
echo $hms['longtext']; //returns 20 minutes, 25.8 seconds

$hms = hms_conversion(2,3,7,0);
echo $hms['text']; //returns 2:03:07

$hms = hms_conversion(2,3,7,0);
echo $hms['hh']; //returns 2

$hms = hms_conversion(2,3,7,0);
echo $hms['mm']; //returns 03

$hms = hms_conversion(2,3,7,0);
echo $hms['ss']; //returns 07

$hms = hms_conversion(2,3,7,0);
echo $hms['minutes']; //returns 3

You can also see a good working example of this on the pace charts that we published over on our running log.


Comments

Loading…

This post was published on June 30th, 2013 by Robert James Reese in PHP. Before using any of the code or other content in this post, you must read and agree to our terms of use.