Home > Uncategorized > Fuzzy Datetime

Fuzzy Datetime

February 3rd, 2009 Chris Leave a comment Go to comments

Judging by traffic statistics, it seems that lot of people are trying to find ‘fuzzy time’ logic. Can’t blame them. So was I.

Well, after some other assorted work, I realized that although my fuzzy_time() function worked pretty well, it didn’t cut it in all cases.  Sometimes, you need a bit more detail than “about five months ago” but aren’t interested in the Unix timestamp of the event, exactly.  So, I came up with a fuzzy_datetime() function, in the spirit of it’s predecessor. Here’s some sample output:

-1 second: 04:31pm
-1 minute: 04:30pm
-1 hour  : 03:31pm
-1 day   : Yesterday at 04:31pm
-3 days  : Saturday (3 days ago) at 04:31pm
-1 week  : January 27th at 04:31pm
-1 month : January 3rd at 04:31pm
-4 months: October 3rd at 04:31pm
-8 months: June 3rd, 2008
-2 years : February 3rd, 2007

Enjoy.

/* Function: fuzzy_datetime
   * Author: Chris Tonkinson
   * Description: This is a function to take a time value, and return a user-friendly format
   *              string such as "Nov 17th (2 days ago)", "July 2nd, 2005", etc.
   * Parameters: $time - Any value acceptable to PHP's strtotime() function
   */
  function fuzzy_datetime( $time ) {
    if ( ( $time = strtotime( $time ) ) == false ) {
      return 'an unknown time';
    }
    define( 'NOW',        time() );
    define( 'ONE_MINUTE', 60 );
    define( 'ONE_HOUR',   ONE_MINUTE*60 );
    define( 'ONE_DAY',    ONE_HOUR*24 );
    define( 'ONE_MONTH',  ONE_DAY*30 );
    define( 'ONE_YEAR',   ONE_MONTH*12 );
 
    // sod = start of day :)
    $day = mktime( 0, 0, 0, date( 'm', $time ), date( 'd', $time ), date( 'Y', $time ) );
    $day_now = mktime( 0, 0, 0, date( 'm', NOW ), date( 'd', NOW ), date( 'Y', NOW ) );
    $yesterday = mktime( 0, 0, 0, date( 'm', NOW-ONE_DAY ), date( 'd', NOW-ONE_DAY ), date( 'Y', NOW-ONE_DAY ) );
    $year = date( 'Y', $time );
    $year_now = date( 'Y', NOW );
    $time_ago = (NOW-$time);
 
    // Show the hour and minute, if $time is during 'today'...
    if ( $day == $day_now ) {
      return date( 'h:ia', $time );
    }
 
    // Show a 'Yesterday at' string for values during 'yesterday'...
    if ( $day == $yesterday ) {
      return 'Yesterday at ' . date( 'h:ia', $time );
    }
 
    // Up to six days ago, we use the name of the day (e.g. 'Monday')...
    if ( $time_ago < ONE_DAY*6 ) {
      return date( 'l', $time ) . ' (' . (($day_now-$day)/ONE_DAY) . ' days ago) at ' . date( 'h:ia', $time );
    }
 
    // If $time occured 'this' calendar year, show a month and day name...
    if ( $time_ago < ONE_MONTH*6 || $year == $year_now ) {
      return date( 'F jS', $time ) . ' at ' . date( 'h:ia', $time );
    }
 
    // The default case, we show the month, day of the month, and year...
    return date( 'F jS, Y', $time );
  }
Categories: Uncategorized Tags:
  1. No comments yet.
  1. No trackbacks yet.