关于php:将秒转换为天,小时,分钟和秒

Convert seconds into days, hours, minutes and seconds

我想将变量$uptime(秒)转换为天,小时,分钟和秒。

例:

1
$uptime = 1640467;

结果应该是:

1
18 days 23 hours 41 minutes

这可以通过DateTime类来实现

使用:

1
2
echo secondsToTime(1640467);
# 18 days, 23 hours, 41 minutes and 7 seconds

功能:

1
2
3
4
5
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


这是重写的功能,包括天。我还更改了变量名称,使代码更容易理解......

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**
 * 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;
}

来源:CodeAid() - http://codeaid.net/php/convert-seconds-to-hours-minutes-and-seconds-(php)


根据Julian Moreno的回答,但改为将响应作为字符串(不是数组)给出,只包括所需的时间间隔而不是假设复数。

这个和最高投票答案之间的区别是:

对于259264秒,此代码将给出

3 days, 1 minute, 4 seconds

259264秒,最高投票答案(格拉维?)会给出

3 days, 0 hours, 1 minutes and 4 seconds

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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);
}

我希望这可以帮助别人。


这是一个简单的8行PHP函数,它将一些秒转换为人类可读的字符串,包括大量秒的月数:

PHP函数seconds2human()


1
gmdate("d H:i:s",1640467);

结果将是19 23:41:07。当它比正常日仅一秒钟时,它会增加1天的日值。这就是它显示19的原因。您可以根据需要分解结果并修复此问题。


这里有一些很好的答案,但没有一个满足我的需求。我建立了Glavic的答案,增加了我需要的一些额外功能;

  • 不要打印零。所以"5分钟"而不是"0小时5分钟"
  • 正确处理复数而不是默认为复数形式。
  • 将输出限制为设定数量的单位;所以"2个月,2天"而不是"2个月,2天,1个小时,45分钟"

您可以看到代码here的运行版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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;
}


最简单的方法是创建一个方法,从当前时间$ now返回DateTime :: diff的相对时间的DateTime :: diff,然后可以链接和格式化。例如:-

1
2
3
public function toDateInterval($seconds) {
    return date_create('@' . (($now = time()) + $seconds))->diff(date_create('@' . $now));
}

现在将您的方法调用链接到DateInterval :: format

1
echo $this->toDateInterval(1640467)->format('%a days %h hours %i minutes'));

结果:

1
18 days 23 hours 41 minutes

简短,可靠:

1
2
3
4
function secondsToDHMS($seconds) {
    $s = (int)$seconds;
    return sprintf('%d:%02d:%02d:%02d', $s/86400, $s/3600%24, $s/60%60, $s%60);
}


虽然这是一个很老的问题 - 人们可能会发现这些有用(不是写得很快):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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) ."
"
;
echo d_h_m_s__string2(0*86400+21*3600+57*60+13) ."
"
;

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

结果:

1
2
3
0d21h57m13s
21h57m13s
9d21h57m13s


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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);
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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);

解决方案应该排除0值并设置正确的单数/复数值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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);
    }
}

Glavi?的优秀解决方案的扩展版本,具有整数验证,解决1 s问题,以及数年和数月的额外支持,代价是减少计算机解析友好性以支持更加人性化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
function secondsToHumanReadable(/*int*/ $seconds)/*: string*/ {
    //if you dont need php5 support, just remove the is_int check and make the input argument type int.
    if(!\is_int($seconds)){
        throw new \InvalidArgumentException('Argument 1 passed to secondsToHumanReadable() must be of the type int, '.\gettype($seconds).' given');
    }
    $dtF = new \DateTime ( '@0' );
    $dtT = new \DateTime ("@$seconds" );
    $ret = '';
    if ($seconds === 0) {
        // special case
        return '0 seconds';
    }
    $diff = $dtF->diff ( $dtT );
    foreach ( array (
            'y' => 'year',
            'm' => 'month',
            'd' => 'day',
            'h' => 'hour',
            'i' => 'minute',
            's' => 'second'
    ) as $time => $timename ) {
        if ($diff->$time !== 0) {
            $ret .= $diff->$time . ' ' . $timename;
            if ($diff->$time !== 1 && $diff->$time !== -1 ) {
                $ret .= 's';
            }
            $ret .= ' ';
        }
    }
    return substr ( $ret, 0, - 1 );
}

var_dump(secondsToHumanReadable(1*60*60*2+1)); - > string(16)"2 hours 1 second"


以下是我喜欢使用的一些代码,用于获取两个日期之间的持续时间。它接受两个日期,并为您提供一个很好的句子结构回复。

这是此处的代码的略微修改版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php

function dateDiff($time1, $time2, $precision = 6, $offset = false) {

    // If not numeric then convert texts to unix timestamps

    if (!is_int($time1)) {
            $time1 = strtotime($time1);
    }

    if (!is_int($time2)) {
            if (!$offset) {
                    $time2 = strtotime($time2);
            }
            else {
                    $time2 = strtotime($time2) - $offset;
            }
    }

    // If time1 is bigger than time2
    // Then swap time1 and time2

    if ($time1 > $time2) {
            $ttime = $time1;
            $time1 = $time2;
            $time2 = $ttime;
    }

    // Set up intervals and diffs arrays

    $intervals = array(
            'year',
            'month',
            'day',
            'hour',
            'minute',
            'second'
    );
    $diffs = array();

    // Loop thru all intervals

    foreach($intervals as $interval) {

            // Create temp time from time1 and interval

            $ttime = strtotime('+1 ' . $interval, $time1);

            // Set initial values

            $add = 1;
            $looped = 0;

            // Loop until temp time is smaller than time2

            while ($time2 >= $ttime) {

                    // Create new temp time from time1 and interval

                    $add++;
                    $ttime = strtotime("+" . $add ."" . $interval, $time1);
                    $looped++;
            }

            $time1 = strtotime("+" . $looped ."" . $interval, $time1);
            $diffs[$interval] = $looped;
    }

    $count = 0;
    $times = array();

    // Loop thru all diffs

    foreach($diffs as $interval => $value) {

            // Break if we have needed precission

            if ($count >= $precision) {
                    break;
            }

            // Add value and interval
            // if value is bigger than 0

            if ($value > 0) {

                    // Add s if value is not 1

                    if ($value != 1) {
                            $interval.="s";
                    }

                    // Add value and interval to times array

                    $times[] = $value ."" . $interval;
                    $count++;
            }
    }

    if (!empty($times)) {

            // Return string with times

            return implode(",", $times);
    }
    else {

            // Return 0 Seconds

    }

    return '0 Seconds';
}

资料来源:https://gist.github.com/ozh/8169202


可以使用我编写的Interval类。它也可以以相反的方式使用。

1
2
3
4
5
6
7
8
9
composer require lubos/cakephp-interval

$Interval = new \Interval\Interval\Interval();

// output 2w 6h
echo $Interval->toHuman((2 * 5 * 8 + 6) * 3600);

// output 36000
echo $Interval->toSeconds('1d 2h');

更多信息请访问https://github.com/LubosRemplik/CakePHP-Interval


使用DateInterval:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$d1 = new DateTime();
$d2 = new DateTime();
$d2->add(new DateInterval('PT'.$timespan.'S'));

$interval = $d2->diff($d1);
echo $interval->format('%a days, %h hours, %i minutes and %s seconds');

// Or
echo sprintf('%d days, %d hours, %d minutes and %d seconds',
    $interval->days,
    $interval->h,
    $interval->i,
    $interval->s
);

// $interval->y => years
// $interval->m => months
// $interval->d => days
// $interval->h => hours
// $interval->i => minutes
// $interval->s => seconds
// $interval->days => total number of days

我使用的这个解决方案(回到学习PHP的日子)没有任何函数:

1
2
3
4
5
6
7
8
$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";

虽然这是一个老问题,但遇到这个问题的新学员可能会觉得这个答案很有用。


一体化解决方案。没有带零的单位。只生成您指定的单位数(默认为3)。
相当长,也许不是很优雅。定义是可选的,但在大项目中可能派上用场。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
define('OneMonth', 2592000);
define('OneWeek', 604800);  
define('OneDay', 86400);
define('OneHour', 3600);    
define('OneMinute', 60);

function SecondsToTime($seconds, $num_units=3) {        
    $time_descr = array(
               "months" => floor($seconds / OneMonth),
               "weeks" => floor(($seconds%OneMonth) / OneWeek),
               "days" => floor(($seconds%OneWeek) / OneDay),
               "hours" => floor(($seconds%OneDay) / OneHour),
               "mins" => floor(($seconds%OneHour) / OneMinute),
               "secs" => floor($seconds%OneMinute),
                );  

    $res ="";
    $counter = 0;

    foreach ($time_descr as $k => $v) {
        if ($v) {
            $res.=$v."".$k;
            $counter++;
            if($counter>=$num_units)
                break;
            elseif($counter)
                $res.=",";            
        }
    }  
    return $res;
}

随意投票,但一定要在你的代码中尝试。它可能就是你需要的。


1
2
3
4
5
6
7
8
foreach ($email as $temp => $value) {
    $dat = strtotime($value['subscription_expiration']); //$value come from mysql database
//$email is an array from mysqli_query()
    $date = strtotime(date('Y-m-d'));

    $_SESSION['expiry'] = (((($dat - $date)/60)/60)/24)." Days Left";
//you will get the difference from current date in days.
}

$ value来自数据库。 此代码在Codeigniter中。 $ SESSION用于存储用户订阅。 这是强制性的。 我在我的情况下使用它,你可以使用你想要的任何东西。


这是我过去用来从与您的问题相关的另一个日期中减去日期的函数,我的原则是在产品过期之前得到多少天,小时分钟和秒:

1
2
3
4
5
6
7
8
9
$expirationDate = strtotime("2015-01-12 20:08:23");
$toDay = strtotime(date('Y-m-d H:i:s'));
$difference = abs($toDay - $expirationDate);
$days = floor($difference / 86400);
$hours = floor(($difference - $days * 86400) / 3600);
$minutes = floor(($difference - $days * 86400 - $hours * 3600) / 60);
$seconds = floor($difference - $days * 86400 - $hours * 3600 - $minutes * 60);

echo"{$days} days {$hours} hours {$minutes} minutes {$seconds} seconds";