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; Digg Like Time Ago PHP Function.

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.

Share or Bookmark This Post:


Comments

RSS Comments Feed


slemborg's Avatar

slemborg

Looking really good, i'm gonna try it out tomorrow, good job.

Pico RG's Avatar

Pico RG

Thanks for the script, it seems very interesting

Michael's Avatar

Michael

Thanks for the function, but it has an error in it. The 'round' should be 'floor' or 'intval'. As an example, if you pass it a date that is between 23.5 and 24 hours in the past, it will return '24 hours 30+x minutes ago', but it should return '23 hours 30+x minutes ago'.

Matt's Avatar

Matt

Good catch Michael, it should use floor. I will change that. Thanks!

Eric's Avatar

Eric

Thanks Matt, I was looking for just this thing, and it works like a champ. Saved me a bunch of time, I'm sure.

Sushi's Avatar

Sushi

Hey. Great script! Just wondering if it's possible to make the posts the same time format? Mainly because I don't use the comments on my snews install. I had a little poke around but had no luck so far. Any help would be awesome :]

Matt's Avatar

Matt

Sushi,

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's Avatar

Bodo

Hello, I implemented the aboce function into my custom php script and it works fine for the yesterday posts. But the problem is that if I modified the date into the current date the script just shows 18+ hourse instead of minute.

Matt's Avatar

Matt

Bodo,

I'm not sure why that would happen, is the granularity is set to 2?

mochammad ichlas's Avatar

mochammad ichlas

Thanks for the great information. I have a blog discussing web site design tips and usabilty. If you want to take a look.

dave's Avatar

dave

I have no idea what i'm doing wrong (not very good at php) but on a test i did, it is saying "posted 4 decades one year ago" ??????

i'm pretty sure i can't time travel. =]

Matt's Avatar

Matt

Dave,

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's Avatar

dave

hmmm, I'm not really sure, I was trying to add this function to my forum. I'm using a mysql database with the unix time, but like i said i am really rubbish at php (just recently trying to teach myself).

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's Avatar

jason

fantastic function.. i installed. the only problem i am having is that i have my site reload the page as soon as some data is updated. but sometimes it reloads too fast and the function just reads 'posted ago'... but if i immediately refresh, then it corrects to something like 'posted 2 seconds ago'.. any tip on how to fix this?
thanks!

Matt's Avatar

Matt

Jason,

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

Matt's Avatar

Matt

Thanks Aziz! I see now, I was checking the time instead of the difference, I should've looked a little closer. Thanks for posting a solution.

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's Avatar

Joshua F

This is better than sex.

Yogesh's Avatar

Yogesh

Thanks for this, its work perfect for me

Dan's Avatar

Dan

How do I implement this into the following function?:

$time = strtotime($message['pubdate']);

echo sprintf( __('%s', 'twitter-for-wordpress'),' '. date('m/d/Y H:ia', $time). '' );

Matt's Avatar

Matt

Dan, try changing that code to this;

$time = time_ago($message['pubdate']);
echo sprintf( __('%s', 'twitter-for-wordpress'),' '.$time);

Sorry for the slow reply, been crazy busy lately.

Salsan  India's Avatar

Salsan India

thanks for the time ago script. i was doing some r&d to make this.




(optional, not publicly displayed)


(optional)

Pingbacks

  1. Programmer's Goodies

Subscribe

RSS Feed

Archives

Powered by HTML5

HTML5 Powered with CSS3 / Styling, Multimedia, and Semantics