I would like to convert a variable $uptime
which is seconds, into days, hours, minutes and seconds.
Example:
I don't know why some of these answers are ridiculously long or complex. Here's one using the DateTime Class. Kind of similar to radzserg's answer. This will only display the units necessary, and negative times will have the 'ago' suffix...
function calctime($seconds = 0) {
$datetime1 = date_create("@0");
$datetime2 = date_create("@$seconds");
$interval = date_diff($datetime1, $datetime2);
if ( $interval->y >= 1 ) $thetime[] = pluralize( $interval->y, 'year' );
if ( $interval->m >= 1 ) $thetime[] = pluralize( $interval->m, 'month' );
if ( $interval->d >= 1 ) $thetime[] = pluralize( $interval->d, 'day' );
if ( $interval->h >= 1 ) $thetime[] = pluralize( $interval->h, 'hour' );
if ( $interval->i >= 1 ) $thetime[] = pluralize( $interval->i, 'minute' );
if ( $interval->s >= 1 ) $thetime[] = pluralize( $interval->s, 'second' );
return isset($thetime) ? implode(' ', $thetime) . ($interval->invert ? ' ago' : '') : NULL;
}
function pluralize($count, $text) {
return $count . ($count == 1 ? " $text" : " ${text}s");
}
// Examples:
// -86400 = 1 day ago
// 12345 = 3 hours 25 minutes 45 seconds
// 987654321 = 31 years 3 months 18 days 4 hours 25 minutes 21 seconds
EDIT: If you want to condense the above example down to use less variables / space (at the expense of legibility), here is an alternate version that does the same thing:
function calctime($seconds = 0) {
$interval = date_diff(date_create("@0"),date_create("@$seconds"));
foreach (array('y'=>'year','m'=>'month','d'=>'day','h'=>'hour','i'=>'minute','s'=>'second') as $format=>$desc) {
if ($interval->$format >= 1) $thetime[] = $interval->$format . ($interval->$format == 1 ? " $desc" : " {$desc}s");
}
return isset($thetime) ? implode(' ', $thetime) . ($interval->invert ? ' ago' : '') : NULL;
}
This can be achieved with DateTime class
Use:
echo secondsToTime(1640467);
# 18 days, 23 hours, 41 minutes and 7 seconds
Function:
function secondsToTime($seconds) {
$dtF = new \DateTime('@0');
$dtT = new \DateTime("@$seconds");
return $dtF->diff($dtT)->format('%a days, %h hours, %i minutes and %s seconds');
}
demo
Solution that should exclude 0 values and set correct singular/plural values
use DateInterval;
use DateTime;
class TimeIntervalFormatter
{
public static function fromSeconds($seconds)
{
$seconds = (int)$seconds;
$dateTime = new DateTime();
$dateTime->sub(new DateInterval("PT{$seconds}S"));
$interval = (new DateTime())->diff($dateTime);
$pieces = explode(' ', $interval->format('%y %m %d %h %i %s'));
$intervals = ['year', 'month', 'day', 'hour', 'minute', 'second'];
$result = [];
foreach ($pieces as $i => $value) {
if (!$value) {
continue;
}
$periodName = $intervals[$i];
if ($value > 1) {
$periodName .= 's';
}
$result[] = "{$value} {$periodName}";
}
return implode(', ', $result);
}
}
The solution for this one I used (back to the days while learning PHP) without any in-functions:
$days = (int)($uptime/86400); //1day = 86400seconds
$rdays = (uptime-($days*86400));
//seconds remaining after uptime was converted into days
$hours = (int)($rdays/3600);//1hour = 3600seconds,converting remaining seconds into hours
$rhours = ($rdays-($hours*3600));
//seconds remaining after $rdays was converted into hours
$minutes = (int)($rhours/60); // 1minute = 60seconds, converting remaining seconds into minutes
echo "$days:$hours:$minutes";
Though this was an old question, new learners who come across this, may find this answer useful.
A variation on @Glavić's answer - this one hides leading zeros for shorter results and uses plurals in correct places. It also removes unnecessary precision (e.g. if the time difference is over 2 hours, you probably don't care how many minutes or seconds).
function secondsToTime($seconds)
{
$dtF = new \DateTime('@0');
$dtT = new \DateTime("@$seconds");
$dateInterval = $dtF->diff($dtT);
$days_t = 'day';
$hours_t = 'hour';
$minutes_t = 'minute';
$seconds_t = 'second';
if ((int)$dateInterval->d > 1) {
$days_t = 'days';
}
if ((int)$dateInterval->h > 1) {
$hours_t = 'hours';
}
if ((int)$dateInterval->i > 1) {
$minutes_t = 'minutes';
}
if ((int)$dateInterval->s > 1) {
$seconds_t = 'seconds';
}
if ((int)$dateInterval->d > 0) {
if ((int)$dateInterval->d > 1 || (int)$dateInterval->h === 0) {
return $dateInterval->format("%a $days_t");
} else {
return $dateInterval->format("%a $days_t, %h $hours_t");
}
} else if ((int)$dateInterval->h > 0) {
if ((int)$dateInterval->h > 1 || (int)$dateInterval->i === 0) {
return $dateInterval->format("%h $hours_t");
} else {
return $dateInterval->format("%h $hours_t, %i $minutes_t");
}
} else if ((int)$dateInterval->i > 0) {
if ((int)$dateInterval->i > 1 || (int)$dateInterval->s === 0) {
return $dateInterval->format("%i $minutes_t");
} else {
return $dateInterval->format("%i $minutes_t, %s $seconds_t");
}
} else {
return $dateInterval->format("%s $seconds_t");
}
}
php > echo secondsToTime(60);
1 minute
php > echo secondsToTime(61);
1 minute, 1 second
php > echo secondsToTime(120);
2 minutes
php > echo secondsToTime(121);
2 minutes
php > echo secondsToTime(2000);
33 minutes
php > echo secondsToTime(4000);
1 hour, 6 minutes
php > echo secondsToTime(4001);
1 hour, 6 minutes
php > echo secondsToTime(40001);
11 hours
php > echo secondsToTime(400000);
4 days
function seconds_to_time($seconds){
// extract hours
$hours = floor($seconds / (60 * 60));
// extract minutes
$divisor_for_minutes = $seconds % (60 * 60);
$minutes = floor($divisor_for_minutes / 60);
// extract the remaining seconds
$divisor_for_seconds = $divisor_for_minutes % 60;
$seconds = ceil($divisor_for_seconds);
//create string HH:MM:SS
$ret = $hours.":".$minutes.":".$seconds;
return($ret);
}