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: