我想知道在给定一定秒数的情况下计算人类可读时间的最优雅方式是什么。我想用PHP写这个。
以下是所需的输出:
我尝试过不同的解决方案,这些解决方案很笨拙且充满条件语句,但我希望有一种更加递归和“干净的代码”方法。
答案 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;
}