以最小的单位获取时差(为了论证,假设为秒)。
然后得到一个限制,告诉你什么时候从一个近似值过渡到下一个近似值。
例如
<?php
$appro = array(
array( 1, 'second', 60 ), // Up to 60 seconds it's seconds
array(60, 'minute', 60 ), // Divide by 60, get minutes. Up to 60 minutes is OK
array(60, 'hour', 24), // Divide by 60, get hours. Up to 24 is OK
array(24, 'day', 7), // Divide by 24, get days.
array(7, 'week', 5), // Divide by 7 to get weeks
array(30.0/7.0, 'month', 12), // Re-multiply by 7 and divide by 30: months
array(365.0/30.0, 'year', 99), // Get days again, divide by 365
);
$timediff = 366*24*3600; // Get this timediff somehow, in seconds
$ap = $timediff;
foreach($appro as $check)
{
list($scale, $name, $maximum) = $check;
$ap /= $scale;
if ($ap < $maximum)
{
print "Scale=$scale, $ap\n";
$what = $name;
switch (floor($ap))
{
case 0: $what = "less than one $name"; break;
case 1: $what = "one $name"; break;
default: $what = floor($ap) . " {$name}s"; break;
}
break;
}
}
print "This was $what ago.";
?>
当然,这会说1.5年前是“一年前”。可以修改算法,让余数乘以$scale
下面的单位渲染,这样1.5年就变成了“一年零六个月”。这有时也让人有点尴尬,因为 9 天变成了“一周零两天前”。
如果近似正确,可以扩展算法并尝试在最合适的单位(上面的一个和下面的一个)中渲染一个周期,最后选择最短的形式(所以“九天”胜过“一周和两天”,“六周”胜过“一个月零两周”)。