Grow your CSS skills. Land your dream job.

Last updated on:

Time Ago Function

This can be used for comments and other from of communication to tell the time ago instead of the exact time which might not be correct to some one in another time zone.

The function only uses unix time stamp like the result of time();

Technique #1

<?php
function ago($time)
{
   $periods = array("second", "minute", "hour", "day", "week", "month", "year", "decade");
   $lengths = array("60","60","24","7","4.35","12","10");

   $now = time();

       $difference     = $now - $time;
       $tense         = "ago";

   for($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) {
       $difference /= $lengths[$j];
   }

   $difference = round($difference);

   if($difference != 1) {
       $periods[$j].= "s";
   }

   return "$difference $periods[$j] 'ago' ";
}
?>

Technique #2

function _ago($tm,$rcs = 0) {
   $cur_tm = time(); $dif = $cur_tm-$tm;
   $pds = array('second','minute','hour','day','week','month','year','decade');
   $lngh = array(1,60,3600,86400,604800,2630880,31570560,315705600);
   for($v = sizeof($lngh)-1; ($v >= 0)&&(($no = $dif/$lngh[$v])<=1); $v--); if($v < 0) $v = 0; $_tm = $cur_tm-($dif%$lngh[$v]);

   $no = floor($no); if($no <> 1) $pds[$v] .='s'; $x=sprintf("%d %s ",$no,$pds[$v]);
   if(($rcs == 1)&&($v >= 1)&&(($cur_tm-$_tm) > 0)) $x .= time_ago($_tm);
   return $x;
}

Needs a time() value, and it will tell you how many seconds/minutes/hours/days/years/decades ago.

Comments

  1. Kenrick
    Permalink to comment#

    YAY my time ago function is up !!!!

  2. In the first technique, you don’t need the single quotes around ‘ago’ in the return line, unless you were to use


    return $difference . $periods[$j] . ' ago';

    Or something along those lines

    • TeMc
      Permalink to comment#

      Indeed, the ‘ago’ isn’t only redundant it also breaks the flow when used inline like:

      <?php
      echo "It was done about " . ago($specialTime) . "). Byebye.";
      ?>

      Instead simply fix it by using $tense as defined

      return "$difference $periods[$j] $tense ";

  3. Permalink to comment#

    the second function is taken from php.net

    http://www.php.net/manual/en/function.time.php#91864

    and it should be corrected from

    function _ago($tm,$rcs = 0) {

    to

    function time_ago($tm,$rcs = 0) {

    otherwise you’ll get it wrong.

  4. Xcoder
    Permalink to comment#

    Very useful, thanks alot!

  5. If you make some minor changes, you can specify how many smaller units should be appended to the string (using the 2nd parameter).

    Just replace the 7th line with this:

    if(($rcs > 0)&&($v >= 1)&&(($cur_tm-$_tm) > 0)) $x .= time_ago($_tm, --$rcs);

    Example:

    time_ago(1291809455) will return “1 month”
    time_ago(1291809455, 1) will return “1 month 2 weeks” (this works without changing the original)
    time_ago(1291809455, 2) will return “1 month 2 weeks 4 days”
    etc.

    • Nick Newman
      Permalink to comment#

      this function brings up a error

      I posted it here:

      http://www.phpfreaks.com/forums/index.php?topic=349575.0

    • Permalink to comment#

      Hi all,
      Based in second function, but for ouput spanish dates

      
      function TimeAgoEs($tm,$rcs = 0) {
      	/*$tm = timeint
      		strtotime("2011/01/14 23:10");
      	*/
         $cur_tm = time(); $dif = $cur_tm-$tm;
         $pds = array('segundo','minuto','hora','dia','semana','mes','año','decada');
         $lngh = array(1,60,3600,86400,604800,2630880,31570560,315705600);
         for($v = sizeof($lngh)-1; ($v >= 0)&&(($no = $dif/$lngh[$v])<=1); $v--); if($v < 0) $v = 0; $_tm = $cur_tm-($dif%$lngh[$v]);
         $no = floor($no);
         if ($v == 5) $pds[$v] .='es'; elseif($no  1) $pds[$v] .='s'; $x=sprintf("%d %s ",$no,$pds[$v]);
         if(($rcs > 0)&&($v >= 1)&&(($cur_tm-$_tm) > 0)) $x .= TimeAgoEs($_tm, --$rcs);
         return $x;
      }

      modified:

       if ($v == 5) $pds[$v] .='es'; elseif($no  1) $pds[$v] .='s'; $x=sprintf("%d %s ",$no,$pds[$v]);

      Outputs:
      dia,dias,semana,semanas,mes,meses,año,años,decada,decadas

      Tips:
      $timeint = strtotime(’2012-01-01 10:09:09′);

  6. Used this for my forum latest posts, thanks a lot for this worked perfectly!

  7. Thank you for this snippet! It has served me well in a Facebook Application that I am developing currently. I’ve left you guys a nice comment credit in the source code.

  8. nice :( but mine not working :( please help me :(( :DD thank you very much :DD :DD

  9. d3vlabs
    Permalink to comment#

    demo ? example ?

    are we talking about like

    It’s been “10 minutes, 28 seconds” since user last posted
    or we talking

    article “updated 7 minuts ago”?

    • Nathan
      Permalink to comment#

      Try it for yourself. :) It’s simple as copy and pasting the function and calling it like this:

      ago( time() – 777 );

      If you just put time() it will say “0 seconds ago” :P

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

  11. b00f
    Permalink to comment#

    Here’s a short one:

    function ago($i){
        $m = time()-$i; $o='just now';
        $t = array('year'=>31556926,'month'=>2629744,'week'=>604800,
    'day'=>86400,'hour'=>3600,'minute'=>60,'second'=>1);
        foreach($t as $u=>$s){
            if($s<=$m){$v=floor($m/$s); $o="$v $u".($v==1?'':'s').' ago'; break;}
        }
        return $o;
    }
  12. Great little script, this has saved me some time :))

  13. Mutebi
    Permalink to comment#

    Hi guys, thanx the good work! Your site has been so helpful here in Africa

  14. Permalink to comment#

    I created an Objective-C port of your PHP function. I hope that’s Ok with you

    here’s the link: http://yawn4life.blogspot.com/2012/08/n-days-ago-objective-c.html

  15. Permalink to comment#

    function worked on the first try, just removed the quotes ‘AGO’. AWESOME!!

  16. Kezy
    Permalink to comment#

    Awesome! the function really worked fine and it’s far better than the longer version i wrote. thanks!!
    Added my own little modification though:


    return "$difference $periods[$j] $tense (".date( "D, F j, o", $time).")";

    displays something like:

    1 week ago (Sun, September 30, 2012)

    • Nathan
      Permalink to comment#

      Awesome modification :)

    • Permalink to comment#

      asaSAsaSAsASasa

    • Keisa
      Permalink to comment#

      Kezy, do you use wordpress? If so do you mind helping me set up my time ago function? I tried using the instructions “Valtid” posted on my previous comment but the results said my post was publised a day ago when I had just posted it a second before I viewed my post :(

  17. Nathan
    Permalink to comment#

    This is an awesome script. Thanks a lot!

    Although I use the jQuery timeago plugin as it auto updates (without refreshing the page) and handles timezones and such out of the box, I like to use this in titles and other stuff that timeago doesn’t work on.

    For example on a site I’m making, when someone edits a comment I like the title of “(edited)” to be something like “This comment has been edited 2 times (last edited 14 minutes ago)”.

  18. Keisa
    Permalink to comment#

    I’m no professional at php. So I have absolutely no idea what to do with this code..
    I’m using WordPress so do I past the code inside my functions.php file?
    If so how EXACTLY can I call it to my posts?
    Or what? I’m lost, please help!

  19. Permalink to comment#

    @keisa

    go to your template e.g. page.php or single.php

    and do something like this…

    echo ago(strtotime(get_the_date()) );

    So you are saying print the date, but first convert string to a time (unix time)

    hope that helps somehow…

    on functions.php you are just defining the function meaning creating it, then you can use it anywhere you want. e.g. single.php thats how php functions work… which that’s what ‘ago’ is, a php function that can be reused later.

  20. sandeep
    Permalink to comment#

    best solution ever

    Day
    Month
    YYYY

    select one
    <?php
    for($i=1;$i<32;$i++){
    echo "$i”;
    }
    ?>

    select one
    <?php
    for($i=1;$i<13;$i++){
    echo "$i”;
    }
    ?>

    select one
    <?php
    for($i=1901;$i<2002;$i++){
    echo "$i”;
    }
    ?>

    <?php
    if(isset($_POST['Submit']))
    {
    $c = array($_POST['day'], $_POST['month'], $_POST['year']);
    $e = implode('-', $c);
    }
    echo "Age Calculator";

    date_default_timezone_set('Asia/Calcutta');
    $localtime = getdate();

    $dob = "$e";
    //$today = date("d-m-Y");
    $today = $localtime['mday']."-".$localtime['mon']."-".$localtime['year'];

    $dob_a = explode("-", $dob);
    $today_a = explode("-", $today);

    $dob_d = $dob_a[0];
    $dob_m = $dob_a[1];
    $dob_y = $dob_a[2];

    $today_d = $today_a[0];
    $today_m = $today_a[1];
    $today_y = $today_a[2];

    $years = $today_y – $dob_y;
    $months = $today_m – $dob_m;

    if ($today_m.$today_d < $dob_m.$dob_d) {
    $years–;
    $months = 12 + $today_m – $dob_m;

    }

    if ($today_d < $dob_d) {
    $months–;
    }

    $firstMonths=array(1,3,5,7,8,10,12);
    $secondMonths=array(4,6,9,11);
    $thirdMonths=array(2);

    if($today_m – $dob_m == 1) {
    if(in_array($dob_m, $firstMonths)) {
    array_push($firstMonths, 0);
    }elseif(in_array($dob_m, $secondMonths)) {
    array_push($secondMonths, 0);
    }elseif(in_array($dob_m, $thirdMonths)) {
    array_push($thirdMonths, 0);
    }
    }

    echo " Age is $years years”;
    ?>

    <input name="" type="text" value="” disabled=”disabled”/>

  21. Love this, thanks guys. Add you to the comments in my code as I’ll be using this for a startup I’m developing.

    One addition I made is a preg_match() to the input variable at the beginning of the function:


    if (preg_match('/\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2}/u', $time))
    {
    $time = strtotime($time);
    }

    That should (about to test it) test the datetime input variable sent to the function for this format 2003-03-11 17:51:00 and convert it to unix time. I added this because I store dates in my database in non-unix format for convenience.

    Matt

  22. Thank you so much!

    Side note: If you want the decade output then you need to change the for line to be:

    …&& $j < count($lengths)…

    Since the for loop is already 0 indexed, having it count($lengths)-1 cuts it off early.

  23. Drupal has a nice API function for this:

    https://api.drupal.org/apis/format_interval

  24. Jaffa
    Permalink to comment#

    include<stdio.h>

    int main(){
        return 0;
        }
    
  25. Atef
    Permalink to comment#

    Dude, you’re a life saviour :)

  26. Erik
    Permalink to comment#

    I’ve been working on this issue for a while now and still haven’t been able to get it to work for me. Any pointers? I keep getting “Just now”

        $time = strtotime('2013-10-17T05:14:26');
        echo '<p>' . ago($time) . '</p>';
    
        function ago($i){
            $m = time()-$i; $o='just now';
            $t = array('year'=>31556926,'month'=>2629744,'week'=>604800,
        'day'=>86400,'hour'=>3600,'minute'=>60,'second'=>1);
            foreach($t as $u=>$s){
                if($s<=$m){$v=floor($m/$s); $o="$v $u".($v==1?'':'s').' ago'; break;}
            }
            return $o;
        }
    
    • Erik
      Permalink to comment#

      Wow… How embarrassing. The date today is 2013-08-17T18:50:59… so 2013-10-17T05:14:26 was throwing it off… Great code!

  27. for info… there is a WordPress function human_time_diff()

    http://codex.wordpress.org/Function_Reference/human_time_diff

  28. Permalink to comment#

    Really helpful if we are not using jQuery.
    Thanks for the post

  29. Faruq
    Permalink to comment#

    Thanks; used it today!

Leave a Comment

Current day month ye@r *

*May or may not contain any actual "CSS" or "Tricks".