www.webdeveloper.com
Results 1 to 7 of 7

Thread: Web 2.0 "time ago" - ie. "2 seconds ago"

  1. #1
    Join Date
    May 2008
    Posts
    50

    Web 2.0 "time ago" - ie. "2 seconds ago"

    Hello,

    I found at this link a script that is supposed to be calculating the actual time something was posted compared to now, like facebook, when they say "about a week ago", "2 days ago", etc.

    Here is the script:
    PHP Code:
    //$datefrom is the timestamp for the content , and you can leave the $dateto value to see the current delay

    function TimeAgo($datefrom,$dateto=-1)
    {
    // Defaults and assume if 0 is passed in that
    // its an error rather than the epoch

    if($datefrom<=0) { return "A long time ago"; }
    if(
    $dateto==-1) { $dateto time(); }

    // Calculate the difference in seconds betweeen
    // the two timestamps

    $difference $dateto $datefrom;

    // If difference is less than 60 seconds,
    // seconds is a good interval of choice

    if($difference 60)
    {
    $interval "s";
    }

    // If difference is between 60 seconds and
    // 60 minutes, minutes is a good interval
    elseif($difference >= 60 && $difference<60*60)
    {
    $interval "n";
    }

    // If difference is between 1 hour and 24 hours
    // hours is a good interval
    elseif($difference >= 60*60 && $difference<60*60*24)
    {
    $interval "h";
    }

    // If difference is between 1 day and 7 days
    // days is a good interval
    elseif($difference >= 60*60*24 && $difference<60*60*24*7)
    {
    $interval "d";
    }

    // If difference is between 1 week and 30 days
    // weeks is a good interval
    elseif($difference >= 60*60*24*&& $difference <
    60*60*24*30)
    {
    $interval "ww";
    }

    // If difference is between 30 days and 365 days
    // months is a good interval, again, the same thing
    // applies, if the 29th February happens to exist
    // between your 2 dates, the function will return
    // the 'incorrect' value for a day
    elseif($difference >= 60*60*24*30 && $difference <
    60*60*24*365)
    {
    $interval "m";
    }

    // If difference is greater than or equal to 365
    // days, return year. This will be incorrect if
    // for example, you call the function on the 28th April
    // 2008 passing in 29th April 2007. It will return
    // 1 year ago when in actual fact (yawn!) not quite
    // a year has gone by
    elseif($difference >= 60*60*24*365)
    {
    $interval "y";
    }

    // Based on the interval, determine the
    // number of units between the two dates
    // From this point on, you would be hard
    // pushed telling the difference between
    // this function and DateDiff. If the $datediff
    // returned is 1, be sure to return the singular
    // of the unit, e.g. 'day' rather 'days'

    switch($interval)
    {
    case 
    "m":
    $months_difference floor($difference 60 60 24 /
    29);
    while (
    mktime(date("H"$datefrom), date("i"$datefrom),
    date("s"$datefrom), date("n"$datefrom)+($months_difference),
    date("j"$dateto), date("Y"$datefrom)) < $dateto)
    {
    $months_difference++;
    }
    $datediff $months_difference;

    // We need this in here because it is possible
    // to have an 'm' interval and a months
    // difference of 12 because we are using 29 days
    // in a month

    if($datediff==12)
    {
    $datediff--;
    }

    $res = ($datediff==1) ? "$datediff month ago" "$datediff
    months ago"
    ;
    break;

    case 
    "y":
    $datediff floor($difference 60 60 24 365);
    $res = ($datediff==1) ? "$datediff year ago" "$datediff
    years ago"
    ;
    break;

    case 
    "d":
    $datediff floor($difference 60 60 24);
    $res = ($datediff==1) ? "$datediff day ago" "$datediff
    days ago"
    ;
    break;

    case 
    "ww":
    $datediff floor($difference 60 60 24 7);
    $res = ($datediff==1) ? "$datediff week ago" "$datediff
    weeks ago"
    ;
    break;

    case 
    "h":
    $datediff floor($difference 60 60);
    $res = ($datediff==1) ? "$datediff hour ago" "$datediff
    hours ago"
    ;
    break;

    case 
    "n":
    $datediff floor($difference 60);
    $res = ($datediff==1) ? "$datediff minute ago" :
    "$datediff minutes ago";
    break;

    case 
    "s":
    $datediff $difference;
    $res = ($datediff==1) ? "$datediff second ago" :
    "$datediff seconds ago";
    break;
    }
    return 
    $res;

    I have written quite a few scripts now but this one doesn't look like anything I've done... Can anyone break it down a bit? My site is running WampServer 2.0, and I'm not sure what variable to echo from this.

  2. #2
    Join Date
    Sep 2008
    Location
    Tel Aviv, Berlin, L.A.
    Posts
    165
    Hi,

    you call "$myecho = TimeAgo($contentdate, [$anydatedifferentformNOW])" to flush it as "echo($myecho)"

    ariell.

  3. #3
    Join Date
    May 2008
    Posts
    50
    $myecho = TimeAgo($contentdate, [$anydatedifferentformNOW])

    Can you be a little more specific, please?!

  4. #4
    Join Date
    Sep 2008
    Location
    Tel Aviv, Berlin, L.A.
    Posts
    165

    more specific

    <?php
    // file: cktsTime.class.php

    /**
    * Supposed to manage various date/time isues
    *
    * Serving static method(s) only, thus comes withOUT a Construictor or any members
    *
    */
    class cktsTime {

    /**
    * Calculates elapsed time
    *
    * Uses UNIX timestamp(s) to perform comparisons.
    * Works on a basis timefrom/timeto, whereas timeto is NOW, if argument is omitted.
    *
    * @param int $datefrom REQUIRED time(stamp) FROM which elapsed time has to be calculated
    * @param int $dateto OPTIONAL time(stamp) TO which elapsed time has to be calculated, defaults to
    * CURRENT TIME (as returned by PHP time())
    * @return
    */
    public static function /** @var char*/ timeAgo(
    /** @var int*/ $datefrom,
    /** @var int*/ $dateto = -1
    ) {
    // assume an error if invalid required argument is passed
    if ( ($datefrom = intval($datefrom)) <= 0)
    return('A long time ago.');
    // typecheck optional arg
    if ( ($dateto = intval($dateto)) <= 0)
    $dateto = time();

    // get arithmetic difference between both times
    // protect from "underflow"
    if ( ($difference = ($datefrom - $dateto)) <= 0)
    return('NO time AT ALL elapsed so far.');

    // come to here, $difference holds the "raw" value in SECONDS
    // default return value with SECONDS,
    // this saves ONE check, namely for "< 60"
    $c = 's';
    // for readability, define some defaults
    $min = 60;
    $hour = ($min * 60);
    $day = ($hour * 24);
    $week = ($day * 7);
    $month = ($day * 30);
    $year = (intval($day * 366.5));

    // check for a difference like between one MIN and one HOUR
    if ( ($difference >= $min) && ($difference < $hour))
    $c = 'n';
    // check for a difference like between one HOUR and one DAY
    elseif ( ($difference >= $hour) && ($difference < $day))
    $c = 'h';
    // check for a difference like between one DAY and one WEEK
    elseif ( ($difference >= $day) && ($difference < $week))
    $c = 'd';
    // check for a difference like between one WEEK and one MONTH
    elseif ( ($difference >= $week) && ($difference < $month))
    $c = 'ww';
    // check for a difference like between one MONTH and one YEAR
    elseif ( ($difference >= $month) && ($difference < $year))
    $c = 'm';
    else
    $c = 'y';

    /*
    * Based on the interval, determine the
    * number of units between the two dates
    * From this point on, you would be hard
    * pushed telling the difference between
    * this function and DateDiff. If the $datediff
    * returned is 1, be sure to return the singular
    * of the unit, e.g. 'day' rather 'days'
    */

    // default return char
    $retchar = '';

    // determine interval
    switch($c) { // switch
    case "m": { // month
    $months_difference = floor($difference / 60 / 60 / 24 / 29);
    // generate as lon as current time (dateto) hasn't been reached
    while (
    mktime(
    date("H", $datefrom), date("i", $datefrom),
    date("s", $datefrom), date("n", $datefrom)+($months_difference),
    date("j", $dateto), date("Y", $datefrom)
    ) < $dateto
    )
    $months_difference++;
    // assign difference
    $datediff = $months_difference;
    /**
    * We need this in here because it is possible
    * to have an 'm' interval and a months
    * difference of 12 because we are using 29 days
    * in a month
    */
    if($datediff==12)
    $datediff--;
    $retchar = 'month';
    break;
    } // month

    case "y": { // year
    $datediff = floor($difference / 60 / 60 / 24 / 365);
    $retchar = 'year';
    break;
    } // year
    case "d": { // day
    $datediff = floor($difference / 60 / 60 / 24);
    $retchar = 'day';
    break;
    } // day
    case "ww": { // week
    $datediff = floor($difference / 60 / 60 / 24 / 7);
    $retchar = 'week';
    break;
    } // week
    case "h": { // hour
    $datediff = floor($difference / 60 / 60);
    $retchar = 'hour';
    break;
    } // hour
    case "n": { // minute
    $datediff = floor($difference / 60);
    $retchar = 'minute';
    break;
    } // minute
    case "s": { // second
    $datediff = $difference;
    $retchar = 'second';
    break;
    } // second
    } // switch

    // take care of proper grammar,
    // thus month/months, year/years, and so on
    if ($datediff != 1)
    $retchar .= 's';

    // send home...
    // creating a "value" is actually overhead
    // however, certain environments REQUIRE an ASSIGNMENT prior to return,
    // so, for safety's sake...
    return( ($c = $datediff.' '.$retchar.' ago'));

    } // END timeAgo()

    } // END CLASS

    // class above is easy to use
    // EXAMPLE

    /**
    * You receive a date (from where ever) as a timestamp
    * if you want to know time elapsed until NOW, you simply pass that
    * timestap the (static) class method
    * NOTE: I certainly assume $datereceived to being retrieved from somewhere...
    */

    $timeElapsedUntilNowAsString = cktsTime::timeAgo($datereceived);
    echo('this bla bla bla is '.$timeElapsedUntilNowAsString);
    // puts out 'this bla bla... is one week ago

    /**
    * In case you have a second time (prior to NOW), you passed that one, too.
    * Again, assuming there is a value (int) $datetocompareto
    *
    */
    $timeElapsedBetweenDatesAsString = cktsTime::timeAgo($datereceived,$datetocompareto);

    /**
    * The good things (or ONE of them) with classes is, that you can extend them at any time, NOT
    * breaking any code written prior to changes.
    *
    * Have Fun,
    * ariell.
    */
    ?>

  5. #5
    Join Date
    May 2008
    Posts
    50
    Wow, incredible! Thanks!

  6. #6
    Join Date
    Sep 2008
    Location
    Tel Aviv, Berlin, L.A.
    Posts
    165
    A pleasure. However, keep in mind that all the calculations stuff is not really correct. The class (at least if not modified) does neither handle leap years nor is it addressing the problem of 29 days == month and 366.5 days == year. It's just an adjustment, and maybe a point to start from.

    Best from the south.
    ariell
    programming is understanding

    my most recent baby The Beatles - Fab Four beatlescomplete.com (now with content!)
    if u need help with utf, watch this first Hebrew/American Chars from same table (not very nice, but a working real life example)

  7. #7
    Join Date
    Aug 2008
    Posts
    42
    Quote Originally Posted by ariell View Post
    <?php
    // file: cktsTime.class.php

    /**
    * Supposed to manage various date/time isues
    *
    * Serving static method(s) only, thus comes withOUT a Construictor or any members
    *
    */
    class cktsTime {

    /**
    * Calculates elapsed time
    *
    * Uses UNIX timestamp(s) to perform comparisons.
    * Works on a basis timefrom/timeto, whereas timeto is NOW, if argument is omitted.
    *
    * @param int $datefrom REQUIRED time(stamp) FROM which elapsed time has to be calculated
    * @param int $dateto OPTIONAL time(stamp) TO which elapsed time has to be calculated, defaults to
    * CURRENT TIME (as returned by PHP time())
    * @return
    */
    public static function /** @var char*/ timeAgo(
    /** @var int*/ $datefrom,
    /** @var int*/ $dateto = -1
    ) {
    // assume an error if invalid required argument is passed
    if ( ($datefrom = intval($datefrom)) <= 0)
    return('A long time ago.');
    // typecheck optional arg
    if ( ($dateto = intval($dateto)) <= 0)
    $dateto = time();

    // get arithmetic difference between both times
    // protect from "underflow"
    if ( ($difference = ($datefrom - $dateto)) <= 0)
    return('NO time AT ALL elapsed so far.');

    // come to here, $difference holds the "raw" value in SECONDS
    // default return value with SECONDS,
    // this saves ONE check, namely for "< 60"
    $c = 's';
    // for readability, define some defaults
    $min = 60;
    $hour = ($min * 60);
    $day = ($hour * 24);
    $week = ($day * 7);
    $month = ($day * 30);
    $year = (intval($day * 366.5));

    // check for a difference like between one MIN and one HOUR
    if ( ($difference >= $min) && ($difference < $hour))
    $c = 'n';
    // check for a difference like between one HOUR and one DAY
    elseif ( ($difference >= $hour) && ($difference < $day))
    $c = 'h';
    // check for a difference like between one DAY and one WEEK
    elseif ( ($difference >= $day) && ($difference < $week))
    $c = 'd';
    // check for a difference like between one WEEK and one MONTH
    elseif ( ($difference >= $week) && ($difference < $month))
    $c = 'ww';
    // check for a difference like between one MONTH and one YEAR
    elseif ( ($difference >= $month) && ($difference < $year))
    $c = 'm';
    else
    $c = 'y';

    /*
    * Based on the interval, determine the
    * number of units between the two dates
    * From this point on, you would be hard
    * pushed telling the difference between
    * this function and DateDiff. If the $datediff
    * returned is 1, be sure to return the singular
    * of the unit, e.g. 'day' rather 'days'
    */

    // default return char
    $retchar = '';

    // determine interval
    switch($c) { // switch
    case "m": { // month
    $months_difference = floor($difference / 60 / 60 / 24 / 29);
    // generate as lon as current time (dateto) hasn't been reached
    while (
    mktime(
    date("H", $datefrom), date("i", $datefrom),
    date("s", $datefrom), date("n", $datefrom)+($months_difference),
    date("j", $dateto), date("Y", $datefrom)
    ) < $dateto
    )
    $months_difference++;
    // assign difference
    $datediff = $months_difference;
    /**
    * We need this in here because it is possible
    * to have an 'm' interval and a months
    * difference of 12 because we are using 29 days
    * in a month
    */
    if($datediff==12)
    $datediff--;
    $retchar = 'month';
    break;
    } // month

    case "y": { // year
    $datediff = floor($difference / 60 / 60 / 24 / 365);
    $retchar = 'year';
    break;
    } // year
    case "d": { // day
    $datediff = floor($difference / 60 / 60 / 24);
    $retchar = 'day';
    break;
    } // day
    case "ww": { // week
    $datediff = floor($difference / 60 / 60 / 24 / 7);
    $retchar = 'week';
    break;
    } // week
    case "h": { // hour
    $datediff = floor($difference / 60 / 60);
    $retchar = 'hour';
    break;
    } // hour
    case "n": { // minute
    $datediff = floor($difference / 60);
    $retchar = 'minute';
    break;
    } // minute
    case "s": { // second
    $datediff = $difference;
    $retchar = 'second';
    break;
    } // second
    } // switch

    // take care of proper grammar,
    // thus month/months, year/years, and so on
    if ($datediff != 1)
    $retchar .= 's';

    // send home...
    // creating a "value" is actually overhead
    // however, certain environments REQUIRE an ASSIGNMENT prior to return,
    // so, for safety's sake...
    return( ($c = $datediff.' '.$retchar.' ago'));

    } // END timeAgo()

    } // END CLASS

    // class above is easy to use
    // EXAMPLE

    /**
    * You receive a date (from where ever) as a timestamp
    * if you want to know time elapsed until NOW, you simply pass that
    * timestap the (static) class method
    * NOTE: I certainly assume $datereceived to being retrieved from somewhere...
    */

    $timeElapsedUntilNowAsString = cktsTime::timeAgo($datereceived);
    echo('this bla bla bla is '.$timeElapsedUntilNowAsString);
    // puts out 'this bla bla... is one week ago

    /**
    * In case you have a second time (prior to NOW), you passed that one, too.
    * Again, assuming there is a value (int) $datetocompareto
    *
    */
    $timeElapsedBetweenDatesAsString = cktsTime::timeAgo($datereceived,$datetocompareto);

    /**
    * The good things (or ONE of them) with classes is, that you can extend them at any time, NOT
    * breaking any code written prior to changes.
    *
    * Have Fun,
    * ariell.
    */
    ?>


    This is not exact though, as you use 30 as the days on the month. What about February and leap years?

    ANYWAY, I know its probably too late to post on this.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles