所以我有这个函数,它显示自时间戳以来的时间。
现在,如果是60分钟,它会显示"1小时前"。如果是24小时,它会转到"1天前",依此类推。如果是1小时,我怎么能这样做呢?
像
Event occured 58 minutes ago
3 minutes later
Event occured 1 hour 1 minute ago
26 hours later
Event occured 1 day 2 hour ago
function humanTiming($time)
{
$time = time() - $time; // to get the time since that moment
$tokens = array (
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
);
foreach ($tokens as $unit => $text) {
if ($time < $unit) continue;
$numberOfUnits = floor($time / $unit);
return $numberOfUnits.$text.' ago';
}
}
您需要这样修改您的函数:
function humanTiming($time)
{
$time = time() - $time; // to get the time since that moment
$tokens = array (
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
);
$result = '';
$counter = 1;
foreach ($tokens as $unit => $text) {
if ($time < $unit) continue;
if ($counter > 2) break;
$numberOfUnits = floor($time / $unit);
$result .= "$numberOfUnits $text ";
$time -= $numberOfUnits * $unit;
++$counter;
}
return "{$result}ago";
}
在codepad.org上检查结果。
PHP 5.2.0引入了DateTime
对象,这将为该问题提供更好的解决方案。
我将用我对另一个问题的回答来展示它有多容易,不过会稍微编辑一下代码:
$create_time = "2016-08-02 12:35:04";
$current_time="2016-08-02 16:16:02";
$dtCurrent = DateTime::createFromFormat('Y-m-d H:i:s', $current_time);
// to use current timestamp, use the following:
//$dtCurrent = new DateTime();
$dtCreate = DateTime::createFromFormat('Y-m-d H:i:s', $create_time);
$diff = $dtCurrent->diff($dtCreate);
$interval = $diff->format("%y years %m months %d days %h hours %i minutes %s seconds");
$interval
将返回0 years 0 months 0 days 3 hours 40 minutes 58 seconds
让我们现在去掉那些零值。好的旧正则表达式在这里非常有用:
$interval = preg_replace('/(^0| 0) (years|months|days|hours|minutes|seconds)/', '', $interval);
最终,我们得到了我们所需要的:3 hours 40 minutes 58 seconds
您可以使用渐进式计算方法,例如:
$tokens = array (
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
);
$tokenValues = array();
foreach($tokens as $tokenValue => $tokenName)
{
if($time > $tokenValue)
{
$tokenValues[$tokenName] = floor($time ' $tokenValue);
$time -= $tikenValue;
}
if(count($tokenValues) == 2)
{
break;
}
}
然后,您应该在tokenValues中只有2个项目,根据需要进行调整!
您可以使用diff查找事件发生时间和当前时间差。例如,请参阅以下代码
$time1 = new DateTime('2013-11-21 12:59:00'); // Event occurred time
$time2 = new DateTime(date('Y-m-d H:i:s')); // Current time
$interval = $time1->diff($time2);
echo $interval->y . " Year " .$interval->m . " Month " .$interval->d ." Days ". $interval->h . " Hours, " . $interval->i." Mintues, ".$interval->s." seconds <br/>";
我没有时间解释,但这个函数在我测试的时候是有效的。此外,我添加了一个功能来处理当前和未来的时间。如果您为该函数提供准确的当前时间,它将返回'just now'
。如果您向它提供过去的时间,它将返回一个以'ago'
结尾的字符串。如果您为它提供将来的时间,它将返回一个以'later'
结尾的字符串。另一个特征是时间单位的自动单数/复数形式。你自己试试吧!
function timeEllapsedFrom($from) {
$time = time() - $from;
$diff = abs($time);
$tokens = array (
'year' => 31536000,
'month' => 2592000,
'week' => 604800,
'day' => 86400,
'hour' => 3600,
'minute' => 60,
'second' => 1
);
$result = array();
foreach ($tokens as $id => $length) {
$value = floor($diff/$length);
if ($value) $result[] = "$value $id" . ($value > 1 ? 's' : '');
$diff -= $length*$value;
}
if (!count($result)) return 'just now';
return join(', ', $result) . ($time < 0 ? ' later' : ' ago');
}
你可以用这个代码测试它:
echo timeEllapsedFrom(time() - 604800 - 7200 - 480 - 24);
它将输出:
1 week, 2 hours, 8 minutes, 24 seconds ago
希望它能有所帮助!
使用DateTime
类。适用于过去和未来的时间戳,并在需要时更正复数:
function elapsedTime($time)
{
date_default_timezone_set('UTC');
$given_time = new DateTime("@$time");
$current_time = new DateTime();
$diff = $given_time->diff($current_time);
$timemap = array('y' => 'year',
'm' => 'month',
'd' => 'day',
'h' => 'hour',
'i' => 'minute',
's' => 'second');
$timefmt = array();
foreach ($timemap as $prop => $desc) {
if ($diff->$prop > 0) {
$timefmt[] = ($diff->$prop > 1)
? "{$diff->$prop} {$desc}s"
: "{$diff->$prop} $desc";
}
}
return (!$timefmt)
? 'just now'
: ((count($timefmt) > 1)
? $diff->format(sprintf('%s and %s',
implode(', ', array_slice($timefmt, 0, -1)), end($timefmt)))
: end($timefmt))
. (($given_time < $current_time) ? ' ago' : ' later');
}
测试:
var_dump(elapsedTime(strtotime('1987-11-25 11:40')));
# string(69) "25 years, 11 months, 29 days, 17 hours, 50 minutes and 42 seconds ago"
var_dump(elapsedTime(time()));
# string(8) "just now"
var_dump(elapsedTime(strtotime('2013-11-25')));
# string(41) "18 hours, 29 minutes and 18 seconds later"