2011-11-13 18 views
2

最近我一直面对“X小时前”,“X天前”功能的网站。 (包括计算器)“大约一小时前”PHP/SQL中的逻辑以及它如何影响性能?

赞, Anil在一个小时前打了一场比赛。 Anil在2天前平了。刚刚发布此评论的是 。

我知道它可以很容易地用一个小函数来完成,它计算旧时间到当前时间,以秒(或毫秒)计算差值并相应返回一个字符串值。

我想问的是;

  1. 如何以最专业的方式来完成?使用PHP计算时差或在查询时使用我们的SQL进行计算?
  2. 它不会降低性能吗?想象一下有100条评论的页面,该功能将工作100次,因此页面加载速度会变慢。

Ps。我不在寻找脚本。

回答

0

我的建议是用PHP计算差异。

你可以做的是在你的数据库中有一个时间戳(考虑一个中性时区),然后进行查询,以便显示任何适合你的间隔的时间(IE时间戳 - 现在()< N),其中N是你的时间间隔。

在这一点上,你可以使用PHP来翻译从现在起事件日期的差别(这也可以成为动态的客户端 - IE的JavaScript - 为最近的条目,所以涵盖的易趣确实秒/分钟的经过到期行动)。

为什么我不会把数据库中的逻辑的原因是因为我觉得这样的数据是应用相关的,而不是依赖分贝 - IE有一天,你可能想显示以另一种方式的时间差,和db不能成为你手头上最多才多艺的工具 - 不一定是因为性能(我认为无论如何,这种影响可能是微不足道的)。

3

我认为性能的含义是可以忽略的。你也可以在客户端通过向客户发送正常的时间戳来做到这一点,例如,对于网络有一个jQuery的插件,这样做:jquery-timeago

我建议在客户端执行此操作,因为此处客户端可以按照希望进行刷新(例如,当页面保持打开时间更长时)。如果需要,也可以向用户提供绝对数据。

+1

我同意这应该在客户端完成; – Qchmqs

+3

如果您在客户端执行此操作,则必须发送服务器的当前时间戳以用作参考。你不能认为人们已经正确设置了他们的时钟。 –

+0

@SalmanA:时间戳应该在某个普通时区,例如GMT/UTC。 – ZeissS

0

从数据库中提取数据后,几乎可以肯定最好做为独立功能。

它当然会产生一个小的开销......但是当开销与开展页面所花费的所有其他开销相比时,我预计它甚至不可能测量(除非您算法效率非常低)。

此外,由于数据库通常是瓶颈,而不是应用程序服务器的CPU,因此在应用程序服务器而不是数据库上执行此类工作通常是个好主意。

5

通常的做法是使用普通的SQL查询以时间为单位收集整数,然后使用PHP/Javascript进行转换。换句话说,没有什么奇特的。以下是大多数Twitter封装中使用的PHP脚本:

/** 
* Formats a timestamp nicely with an adaptive "x units of time ago" message. 
* Based on the original Twitter JavaScript badge. Only handles past dates. 
* @return string Nicely-formatted message for the timestamp. 
* @param $time Output of strtotime() on your choice of timestamp. 
*/ 
function niceTime($time) { 
    $delta = time() - $time; 
    if ($delta < 60) { 
    return 'less than a minute ago.'; 
    } else if ($delta < 120) { 
    return 'about a minute ago.'; 
    } else if ($delta < (45 * 60)) { 
    return floor($delta/60) . ' minutes ago.'; 
    } else if ($delta < (90 * 60)) { 
    return 'about an hour ago.'; 
    } else if ($delta < (24 * 60 * 60)) { 
    return 'about ' . floor($delta/3600) . ' hours ago.'; 
    } else if ($delta < (48 * 60 * 60)) { 
    return '1 day ago.'; 
    } else { 
    return floor($delta/86400) . ' days ago.'; 
    } 
} 
?> 

这通常是如此之快,以至于它应该比平时花费的时间更少。如果您在页面上的计算结果少于300个,则不会看到性能下降。

0

100次几乎没有任何东西仍然几乎没有。不要担心。一个简单的检查如下:

if time > day 
    write time.in_days + " days" 
if time > hour 
    write time.in_hours + " hours" 
if time > minute 
    write time.in_minutes + " minute" 
if time > second 
    write time.in_seconds + " seconds" 
if time > millisecond 
    write time.in_seconds + " milliseconds" 

只会带你几个时钟周期。你将有30亿个时钟周期供你使用,因此一个100个这样的函数调用将达到毫秒的计算量。

0

在sql中,由于语言的原因,计算会花费您的时间来构建。 我的选择将是PHP或JavaScript。 我也听说过这个问题的jQuery解决方案。 JavaScript会将计算成本完全压缩到客户端。

0
  1. 得到时间戳从SQL,
  2. 使用简单的减法来获得秒
  3. 你可以实现一个简单的欧尔数的差值(n)函数,而不是欧尔N,让文本延时,如下所示:
 
function niceTime($difference) { 
    if ($difference > 86400) 
    if ($difference > 2592000) 
     if ($difference > 30758400) { 
     $time = round($difference/30758400); 
     $unit = 'year'; 
     } else { 
     $time = round($difference/2592000); 
     $unit = 'month'; 
     } 
    else 
     if ($difference > 604800) { 
     $time = round($difference/604800); 
     $unit = 'week'; 
     } else { 
     $time = round($difference/86400); 
     $unit = 'day'; 
     } 
    else 
    if ($difference > 900) 
     if ($difference > 3600) { 
     $time = round($difference/3600); 
     $unit = 'hour'; 
     } else { 
     $time = round($difference/900); 
     $unit = 'quarter'; 
     } 
    else 
     if ($difference > 60) { 
     $time = round($difference/60); 
     $unit = 'minute'; 
     } else { 
     $time = round($difference); 
     $unit = 'second'; 
     } 
    return $time . ' ' . $unit . ($time != 1 ? 's' : '') . ' ago'; 
} 

这里的想法是,你不应该通过八步迭代,找出一个给定的差异的确是最坏的情况下(超过一年)。相反,你每次都会将选项分成一半,而且你会在三次比较中以“正确”的时间进行比赛。

在你有100.000评论认为都是两岁页面最坏的情况下,这将减少800.000比较的次数,以300.000,这是noticable。 ;-)

0

我已更改了镰刀所提供的代码,以便为月数,周数和年数添加补贴。

function agoTime($time) { 
$delta = time() - $time; 

if ($delta < 60) { 
    return 'less than a minute ago.'; 
} else if ($delta < 120) { 
return 'about a minute ago.'; 
} else if ($delta < (45 * 60)) { 
return floor($delta/60) . ' minutes ago.'; 
} else if ($delta < (90 * 60)) { 
return 'about an hour ago.'; 
} else if ($delta < (24 * 60 * 60)) { 
return 'about ' . floor($delta/3600) . ' hours ago.'; 
} else if ($delta < (48 * 60 * 60)) { 
return '1 day ago.'; 
} else if ($delta < (11 * 24 * 60 * 60)) { 
return 'about a week ago.'; 
} else if ($delta < (30 * 24 * 60 * 60)) { 
return 'about ' .floor($delta/604800) . ' weeks ago.'; 
} else if ($delta < (45 * 24 * 60 * 60)) { 
return 'more than a month ago.'; 
} else if ($delta < (365 * 24 * 60 * 60)) { 
return 'about ' .floor($delta/2592000) . ' months ago.'; 
} else if ($delta < (550 * 24 * 60 * 60)) { 
return 'more than a year ago.'; 
} else { 
return 'about ' .floor($delta/31536000) . ' years ago.'; 
} 
相关问题