Another variation on the "time ago" PHP function, use MySQL's datetime field type
I was recently looking at writing a function to format the comment post times in the ever trendy "time ago" style... such as;
Matt posted 6 days 3 hours ago
Naturally I first scoured the web for an appropriate existing PHP function, and I came across this one; http://wessite.com/item/2008/11/digg-like-time-ago-php-function (dead link).
Quite useful and fairly complete, but there were a few things I wanted to change, so I've hacked it up and remixed it here to accept a MySQL datetime field type result and then format the output like mentioned above. I also added weeks, months, years, and decades to the function to carry it as far out as anyone would possibly want it to go.
If you're using sNews and want to use this for your comments, simply follow these 2 quick steps.
Step 1) As always, BACK-UP your snews.php file and work off a copy. Now simply copy the function below into your snews.php file, right above the closing php tag;
// DISPLAYS COMMENT POST TIME AS "1 year, 1 week ago" or "5 minutes, 7 seconds ago", etc...
function time_ago($date,$granularity=2) {
$date = strtotime($date);
$difference = time() - $date;
$periods = array('decade' => 315360000,
'year' => 31536000,
'month' => 2628000,
'week' => 604800,
'day' => 86400,
'hour' => 3600,
'minute' => 60,
'second' => 1);
if ($difference < 5) { // less than 5 seconds ago, let's say "just now"
$retval = "posted just now";
return $retval;
} else {
foreach ($periods as $key => $value) {
if ($difference >= $value) {
$time = floor($difference/$value);
$difference %= $value;
$retval .= ($retval ? ' ' : '').$time.' ';
$retval .= (($time > 1) ? $key.'s' : $key);
$granularity--;
}
if ($granularity == '0') { break; }
}
return ' posted '.$retval.' ago';
}
}
Step 2) Now find the function comment, and comment out the existing date format and add the highlighted code like below;
while ($r = mysql_fetch_array($result)) {
//$date = date($date_format, strtotime($r['time']));
$date = time_ago($r['time']);
$commentNum = $offset + $ordinal;
That should do it, now your comment times should be formatted by "time ago". I just thought it may be useful to someone else looking for the functionality.


Comments
RSS Comments Feed
slemborg
Pico RG
Michael
Matt
Eric
Sushi
Matt
Look within the function articles, find the following;
$a_date_format = date(s('date_format'), strtotime($r['date']));
and change it to;
$a_date_format = time_ago($r['date']);
I think that should do it.
Bodo
Matt
I'm not sure why that would happen, is the granularity is set to 2?
mochammad ichlas
dave
i'm pretty sure i can't time travel. =]
Matt
Are you sure you're giving the function a MySQL datetime result? 4 decades ago sounds like maybe you're getting the Unix timestamp due to an invalid date or something along those lines.
dave
Thanks for the reply and all but i think ill just leave it for now until i understand it all a bit better. Cheers.
jason
thanks!
Matt
If it's because it's under 1 second, you could add a simple check in there, like;
if ($time < '1') {
$retval = "less than 1 second";
}
$granularity--;
That's totally untested BTW, may need some tweaking
Aziz Light
The fix above doesn't actually work though. Here is the modified version that fixes the bug that occurs when the time is less then one second ago:
http://pastie.textmate.org/private/8oybjxmhmpqj6dntiuvpg
Matt
I have updated it to say "posted just now" when under 5 seconds, the user can change that to 1 second or any other value they like.
Joshua F
Yogesh
Dan
$time = strtotime($message['pubdate']);
echo sprintf( __('%s', 'twitter-for-wordpress'),' '. date('m/d/Y H:ia', $time). '' );
Matt
$time = time_ago($message['pubdate']);
echo sprintf( __('%s', 'twitter-for-wordpress'),' '.$time);
Sorry for the slow reply, been crazy busy lately.
Salsan India
Charles
Before using $retval .= ..., shouldn't you declare $retval = ''; beforehand?
Thanks for the script!
Matt
It probably is best practice to declare it first with a null value, but the variable will be created when first called, and it should be called within the if/else.
Maybe the MySQL datetime you're sending it isn't valid and therefore $retval is never created? In which case, declaring it would simple return a null value I would think. Not really sure how you used it within your own script, but if you've got it working now, it's all good I suppose.
Eric
Pingbacks