【发布时间】:2009-06-27 14:47:33
【问题描述】:
所以,我的 users 表中有一个名为 last_active 的字段,每次用户重新加载页面时都会更新。
它存储在 unix 时间戳中。
我想这样输出:Last online: 4 d 18 h 19 m ago
如何做到这一点?用php的date()能做到吗?
谢谢。
【问题讨论】:
所以,我的 users 表中有一个名为 last_active 的字段,每次用户重新加载页面时都会更新。
它存储在 unix 时间戳中。
我想这样输出:Last online: 4 d 18 h 19 m ago
如何做到这一点?用php的date()能做到吗?
谢谢。
【问题讨论】:
如果您愿意,可以直接在 MySQL 中实现:
select date_format(from_unixtime(current_timestamp - last_timestamp),
'Last online: %e days, %k hours, %i minutes, %s seconds ago.');
(如果您希望就地计算,current_timestamp 可以替换为 unix_timestamp(now()))
DATE_FORMAT 允许您拥有基于特定日期的自定义字符串。如果您使用两个时间戳之间的差异填充其日期,它将按照您的要求工作。
上述解决方案仅在不到一个月的情况下才有效;如果您想要一年中的几天,请使用 %j。该函数的文档显示更多。
【讨论】:
最简单的方法是使用last_active 时间戳,并使用time() 获取当前时间戳。然后从当前时间戳中减去最后一次活动,然后您只需将结果除以一天中的秒数以获得天数差异,一小时内的秒数获得小时数差异等等。
这种方法在某些特殊情况下(闰年等)可能会稍微不准确,但它应该足以满足您更简单的用例
【讨论】:
在找到几十个损坏或半途而废的解决方案后,我为 UNIX 时间戳构建了以下函数。
您可以限制详细程度...
echo timeDiff(1350297908); 将显示“5 分钟 42 秒前”。echo timeDiff(1350297908, 1); 将仅显示“5 分钟前”。
function timeDiff( $from, $levels=7 ){
$now = time();
$diff = ($from > $now) ? $from - $now : $now - $from;
$status = ($from > $now) ? ' away' : ' ago';
$times = array(31536000, 2628000, 604800, 86400, 3600, 60, 1);
$words = array('year', 'month', 'week', 'day', 'hour', 'minute', 'second');
$str = array();
foreach ($times as $k=>$v){
$val = floor($diff/$v);
if ($val) {
$str[] = $val .' '. $words[$k] . ($val==1 ? '' : 's');
$levels--;
}
$diff %= $v;
if ($levels==0) break;
}
return implode(', ', $str) . $status;
}
【讨论】:
当我需要这种解决方案时,我编写了这个简单的函数(它需要几分钟作为输入):
function minutes_to_time($minutes)
{
$obj = "";
// extract days
$days = floor($minutes/(1440)); # Divide on the daily minutes 60 min * 24 hours
# echo "Days: " . $days;
// extract hours
$hours = floor(($minutes-($days*1440))/60);
# echo " Hours: " . $hours;
// extract left minutes
$minutes = ($minutes-($days*24*60)-($hours*60));
# echo " Minutes: " . $minutes;
if ($days > 0)
{
$obj .= $days . "d ";
}
if ($hours > 0)
{
$obj .= $hours . "h ";
}
if ($minutes >= 0)
{
$obj .= $minutes . "m ";
}
$obj .= "ago";
return $obj;
}
【讨论】: