Php convert seconds to days, hours, minutes

Asked 10 years, 10 months ago

Viewed 183k times

I would like to convert a variable $uptime which is seconds, into days, hours, minutes and seconds.

Example:

$uptime = 1640467;

Result should be:

18 days 23 hours 41 minutes

Glavić

41.7k13 gold badges74 silver badges107 bronze badges

asked Nov 25, 2011 at 20:14

0

This can be achieved with DateTime class

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'];
}

Use:

echo secondsToTime[1640467];
# 18 days, 23 hours, 41 minutes and 7 seconds

demo

Pikamander2

6,3433 gold badges42 silver badges63 bronze badges

answered Oct 30, 2013 at 11:18

GlavićGlavić

41.7k13 gold badges74 silver badges107 bronze badges

11

This is the function rewritten to include days. I also changed the variable names to make the code easier to understand...

/** 
 * Convert number of seconds into hours, minutes and seconds 
 * and return an array containing those values 
 * 
 * @param integer $inputSeconds Number of seconds to parse 
 * @return array 
 */ 

function secondsToTime[$inputSeconds] {

    $secondsInAMinute = 60;
    $secondsInAnHour  = 60 * $secondsInAMinute;
    $secondsInADay    = 24 * $secondsInAnHour;

    // extract days
    $days = floor[$inputSeconds / $secondsInADay];

    // extract hours
    $hourSeconds = $inputSeconds % $secondsInADay;
    $hours = floor[$hourSeconds / $secondsInAnHour];

    // extract minutes
    $minuteSeconds = $hourSeconds % $secondsInAnHour;
    $minutes = floor[$minuteSeconds / $secondsInAMinute];

    // extract the remaining seconds
    $remainingSeconds = $minuteSeconds % $secondsInAMinute;
    $seconds = ceil[$remainingSeconds];

    // return the final array
    $obj = array[
        'd' => [int] $days,
        'h' => [int] $hours,
        'm' => [int] $minutes,
        's' => [int] $seconds,
    ];
    return $obj;
}

Source: CodeAid[] - //codeaid.net/php/convert-seconds-to-hours-minutes-and-seconds-[php]

Matthew

27.3k26 gold badges100 silver badges163 bronze badges

answered Nov 25, 2011 at 20:17

Julian MorenoJulian Moreno

1,0443 gold badges15 silver badges30 bronze badges

6

Based on the answer by Julian Moreno, but changed to give the response as a string [not an array], only include the time intervals required and not assume the plural.

The difference between this and the highest voted answer is:

For 259264 seconds, this code would give

3 days, 1 minute, 4 seconds

For 259264 seconds, the highest voted answer [by Glavić] would give

3 days, 0 hours, 1 minutes and 4 seconds

function secondsToTime[$inputSeconds] {
    $secondsInAMinute = 60;
    $secondsInAnHour = 60 * $secondsInAMinute;
    $secondsInADay = 24 * $secondsInAnHour;

    // Extract days
    $days = floor[$inputSeconds / $secondsInADay];

    // Extract hours
    $hourSeconds = $inputSeconds % $secondsInADay;
    $hours = floor[$hourSeconds / $secondsInAnHour];

    // Extract minutes
    $minuteSeconds = $hourSeconds % $secondsInAnHour;
    $minutes = floor[$minuteSeconds / $secondsInAMinute];

    // Extract the remaining seconds
    $remainingSeconds = $minuteSeconds % $secondsInAMinute;
    $seconds = ceil[$remainingSeconds];

    // Format and return
    $timeParts = [];
    $sections = [
        'day' => [int]$days,
        'hour' => [int]$hours,
        'minute' => [int]$minutes,
        'second' => [int]$seconds,
    ];

    foreach [$sections as $name => $value]{
        if [$value > 0]{
            $timeParts[] = $value. ' '.$name.[$value == 1 ? '' : 's'];
        }
    }

    return implode[', ', $timeParts];
}

I hope this helps someone.

answered May 13, 2017 at 19:04

Luke CousinsLuke Cousins

2,0191 gold badge19 silver badges37 bronze badges

2

Here it is a simple 8-lines PHP function that converts a number of seconds into a human readable string including number of months for large amounts of seconds:

PHP function seconds2human[]

function seconds2human[$ss] {
$s = $ss%60;
$m = floor[[$ss%3600]/60];
$h = floor[[$ss%86400]/3600];
$d = floor[[$ss%2592000]/86400];
$M = floor[$ss/2592000];

return "$M months, $d days, $h hours, $m minutes, $s seconds";
}

answered Aug 25, 2012 at 1:25

snippetsofcodesnippetsofcode

9372 gold badges10 silver badges10 bronze badges

3

gmdate["d H:i:s",1640467];

Result will be 19 23:41:07. Even if the time is an extra 1 second, it causes the day to change. So it turns out 19. You can explode the result for your needs and fix this.

answered Oct 13, 2014 at 16:41

4

There are some very good answers here but none of them covered my needs. I built on Glavic's answer to add some extra features that I needed;

  • Don't print zeros. So "5 minutes" instead of " 0 hours, 5 minutes"
  • Handle plural properly instead of defaulting to the plural form.
  • Limit the output to a set number of units; So "2 months, 2 days" instead of "2 months, 2 days, 1 hour, 45 minutes"

You can see a running version of the code here.

function secondsToHumanReadable[int $seconds, int $requiredParts = null]
{
    $from     = new \DateTime['@0'];
    $to       = new \DateTime["@$seconds"];
    $interval = $from->diff[$to];
    $str      = '';

    $parts = [
        'y' => 'year',
        'm' => 'month',
        'd' => 'day',
        'h' => 'hour',
        'i' => 'minute',
        's' => 'second',
    ];

    $includedParts = 0;

    foreach [$parts as $key => $text] {
        if [$requiredParts && $includedParts >= $requiredParts] {
            break;
        }

        $currentPart = $interval->{$key};

        if [empty[$currentPart]] {
            continue;
        }

        if [!empty[$str]] {
            $str .= ', ';
        }

        $str .= sprintf['%d %s', $currentPart, $text];

        if [$currentPart > 1] {
            // handle plural
            $str .= 's';
        }

        $includedParts++;
    }

    return $str;
}

answered May 10, 2018 at 20:26

Ramy NasrRamy Nasr

2,28719 silver badges24 bronze badges

2

Short, simple, reliable :

function secondsToDHMS[$seconds] {
    $s = [int]$seconds;
    return sprintf['%d:%02d:%02d:%02d', $s/86400, $s/3600%24, $s/60%60, $s%60];
}

answered Jun 19, 2017 at 22:30

3

Laravel example

700+ locales support by Carbon

\Carbon\CarbonInterval::seconds[1640467]->cascade[]->forHumans[]; //2 weeks 4 days 23 hours 41 minutes 7 seconds

answered Dec 23, 2020 at 11:41

the_hasanovthe_hasanov

7297 silver badges14 bronze badges

The simplest approach would be to create a method that returns a DateInterval from the DateTime::diff of the relative time in $seconds from the current time $now which you can then chain and format. For example:-

public function toDateInterval[$seconds] {
    return date_create['@' . [[$now = time[]] + $seconds]]->diff[date_create['@' . $now]];
}

Now chain your method call to DateInterval::format

echo $this->toDateInterval[1640467]->format['%a days %h hours %i minutes']];

Result:

18 days 23 hours 41 minutes

answered Dec 11, 2016 at 21:11

Although it is quite old question - one may find these useful [not written to be fast]:

function d_h_m_s__string1[$seconds]
{
    $ret = '';
    $divs = array[86400, 3600, 60, 1];

    for [$d = 0; $d < 4; $d++]
    {
        $q = [int][$seconds / $divs[$d]];
        $r = $seconds % $divs[$d];
        $ret .= sprintf["%d%s", $q, substr['dhms', $d, 1]];
        $seconds = $r;
    }

    return $ret;
}

function d_h_m_s__string2[$seconds]
{
    if [$seconds == 0] return '0s';

    $can_print = false; // to skip 0d, 0d0m ....
    $ret = '';
    $divs = array[86400, 3600, 60, 1];

    for [$d = 0; $d < 4; $d++]
    {
        $q = [int][$seconds / $divs[$d]];
        $r = $seconds % $divs[$d];
        if [$q != 0] $can_print = true;
        if [$can_print] $ret .= sprintf["%d%s", $q, substr['dhms', $d, 1]];
        $seconds = $r;
    }

    return $ret;
}

function d_h_m_s__array[$seconds]
{
    $ret = array[];

    $divs = array[86400, 3600, 60, 1];

    for [$d = 0; $d < 4; $d++]
    {
        $q = $seconds / $divs[$d];
        $r = $seconds % $divs[$d];
        $ret[substr['dhms', $d, 1]] = $q;

        $seconds = $r;
    }

    return $ret;
}

echo d_h_m_s__string1[0*86400+21*3600+57*60+13] . "\n";
echo d_h_m_s__string2[0*86400+21*3600+57*60+13] . "\n";

$ret = d_h_m_s__array[9*86400+21*3600+57*60+13];
printf["%dd%dh%dm%ds\n", $ret['d'], $ret['h'], $ret['m'], $ret['s']];

result:

0d21h57m13s
21h57m13s
9d21h57m13s

answered Nov 29, 2013 at 13:53

ArturArtur

6,9402 gold badges24 silver badges38 bronze badges

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];
}

answered Apr 12, 2016 at 12:10

James DohertyJames Doherty

1,1711 gold badge7 silver badges6 bronze badges

1

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];
    }
}

answered Sep 14, 2017 at 10:09

radzsergradzserg

1,0981 gold badge9 silver badges22 bronze badges

function convert[$seconds]{
$string = "";

$days = intval[intval[$seconds] / [3600*24]];
$hours = [intval[$seconds] / 3600] % 24;
$minutes = [intval[$seconds] / 60] % 60;
$seconds = [intval[$seconds]] % 60;

if[$days> 0]{
    $string .= "$days days ";
}
if[$hours > 0]{
    $string .= "$hours hours ";
}
if[$minutes > 0]{
    $string .= "$minutes minutes ";
}
if [$seconds > 0]{
    $string .= "$seconds seconds";
}

return $string;
}

echo convert[3744000];

answered Jan 8, 2018 at 13:07

0

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;
}

answered Jan 24, 2020 at 17:42

JasonJason

831 silver badge6 bronze badges

2

an extended version of Glavić's excellent solution , having integer validation, solving the 1 s problem, and additional support for years and months, at the expense of being less computer parsing friendly in favor of being more human friendly:

Chủ Đề