计算人类可读时间的最佳方法

时间:2013-03-21 13:21:51

标签: php algorithm elapsedtime

我想知道在给定一定秒数的情况下计算人类可读时间的最优雅方式是什么。我想用PHP写这个。

以下是所需的输出:

  • elapsedTimeInSeconds>一年,输出“#years,#months”
  • elapsedTimeInSeconds>一个月,输出“#months,#days”
  • elapsedTimeInSeconds>有一天,输出“#days,#hours”
  • elapsedTimeInSeconds>一小时,输出“#hours,#minutes”
  • elapsedTimeInSeconds>一分钟,输出“#minutes,#seconds”

我尝试过不同的解决方案,这些解决方案很笨拙且充满条件语句,但我希望有一种更加递归和“干净的代码”方法。

3 个答案:

答案 0 :(得分:3)

我认为这更灵活,因为您可以轻松添加十年,世纪等新单位,代码不会改变:

$names = array("seconds", "minutes", "hours", "days", "months", "years");
$values = array(1, 60, 3600, 24 * 3600, 30 * 24 * 3600, 365 * 24 * 3600);

$time = ...elapsedTimeInSeconds...;
for($i = count($values) - 1; $i > 0 && $time < $values[$i]; $i--);
if($i == 0) {
    echo intval($time / $values[$i]) . " " . $names[$i];
} else {
    $t1 = intval($time / $values[$i]);
    $t2 = intval(($time - $t1 * $values[$i]) / $values[$i - 1]);
    echo "$t1 " . $names[$i] . ", $t2 " . $names[$i - 1];
}

答案 1 :(得分:2)

感谢您的建议。

我主要使用Waygood和ChrisForrence对这种方法的建议。我尽量保持简单,并引入了简单的参数,如详细级别和分隔符(用于字符串输出)。

public function elapsedTimeHumanReadable($date = null, $detailLevel = 2, $delimiter = ' et ')
{
    if($date === null)
    {
        $date = self::now();
    }

    $sec = $this->elapsedSecond($date);

    $a_sec = 1;
    $a_min = $a_sec * 60;
    $an_hour = $a_min * 60;
    $a_day = $an_hour * 24;
    $a_month = $a_day * 30;
    $a_year = $a_day * 365;

    $text = '';
    $resultStack = array();
    if($sec >= $a_year)
    {
        $years = floor($sec / $a_year);
        $text .= $years . $this->plural($years, ' an');
        $sec = $sec - ($years * $a_year);
        array_push($resultStack, $text);
    }

    if($sec >= $a_month)
    {
        $months = floor($sec / $a_month);
        $text = $months . ' mois';
        $sec = $sec - ($months * $a_month);
        array_push($resultStack, $text);
    }

    if($sec >= $a_day)
    {
        $days = floor($sec / $a_day);
        $text = $days . $this->plural($days, ' jour');
        $sec = $sec - ($days * $a_day);
        array_push($resultStack, $text);
    }

    if($sec >= $an_hour)
    {
        $hours = floor($sec / $an_hour);
        $text = $hours . $this->plural($hours, ' heure');
        $sec = $sec - ($hours * $an_hour);
        array_push($resultStack, $text);
    }

    if($sec >= $a_min)
    {
        $minutes = floor($sec / $a_min);
        $text = $minutes . $this->plural($minutes, ' minute');
        $sec = $sec - ($minutes * $a_min);
        array_push($resultStack, $text);
    }

    if($sec >= $a_sec)
    {
        $seconds = floor($sec / $a_sec);
        $text = $sec . $this->plural($seconds, ' seconde');
        $sec = $sec - ($sec * $a_sec);
        array_push($resultStack, $text);
    }

    $result = $resultStack[0];
    for($i = 1; $i <= $detailLevel - 1; $i++)
    {
        if(!empty($resultStack[$i]))
        {
            $result .= $delimiter . $resultStack[$i];
        }
    }

    return $result;
}

我还添加了一个非常简单的复数函数,以正确的语法方式返回时间单位:

public function plural($value, $unit)
{
    if($value > 1)
    {
        return $unit . 's';
    }
    else
    {
        return $unit;
    }
}

我对for循环并不满意,但它实际上运行正常。

无论如何,非常感谢你的帮助!

答案 2 :(得分:1)

我用这个:

function durationFormat($time)
{
    if(gmdate("Y", $time)>1970) return (1970-gmdate("Y",$time)).gmdate(" \y\r\s ", $time).(gmdate("n",$time)-1).gmdate(" \m\o\n\t\h\s ", $time).(gmdate("j",$time)-1).gmdate(" \d\a\y\s H:i:s", $time);
    if(gmdate("n", $time)>1) return (gmdate("n",$time)-1).gmdate(" \m\o\n\t\h\s ", $time).(gmdate("j",$time)-1).gmdate(" \d\a\y\s H:i:s", $time);
    if(gmdate("j", $time)>1) return (gmdate("j",$time)-1).gmdate(" \d\a\y\s H:i:s", $time);
    return gmdate("H:i:s", $time);
}

它有点快速和肮脏,但做的工作

OR

function durationFormat2($seconds)
{
    $a_sec=1;
    $a_min=$a_sec*60;
    $an_hour=$a_min*60;
    $a_day=$an_hour*24;
    $a_week=$a_day*52;
    //$a_month=$a_day*(floor(365/12));
    $a_month=$a_day*30;
    $a_year=$a_day*365;

    $params=2;
    $text='';
    if($seconds>$a_year)
    {
        $years=floor($seconds/$a_year);
        $text.=$years.' years ';
        $seconds=$seconds-($years*$a_year);
        $params--;
    }
    if($params==0) return $text;
    if($seconds>$a_month)
    {
        $months=floor($seconds/$a_month);
        $text.=$months.' months ';
        $seconds=$seconds-($months*$a_month);
        $params--;
    }
    if($params==0) return $text;
    if($seconds>$a_week)
    {
        $weeks=floor($seconds/$a_week);
        $text.=$weeks.' weeks ';
        $seconds=$seconds-($months*$a_week);
        $params--;
    }
    if($params==0) return $text;
    if($seconds>$a_day)
    {
        $days=floor($seconds/$a_day);
        $text.=$days.' days ';
        $seconds=$seconds-($days*$a_day);
        $params--;
    }
    if($params==0) return $text;
    $H=gmdate("H", $seconds);
    if($H>0)
    {
        $text.=$H.' hours ';
        $params--;
    }
    if($params==0) return $text;
    $M=gmdate("i", $seconds);
    if($M>0)
    {
        $text.=$M.' minutes ';
        $params--;
    }
    if($params==0) return $text;
    $S=gmdate("s", $seconds);
    $text.=$S.' seconds ';

    return $text;
}
相关问题