PHP Function to Compare Time
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

Overview

I need a PHP function compare_time(); to compare a given date/time string (that looks like 03/28/2012 2:45 PM (pattern is MM/DD/YYYY H:MM AM|PM)) to the current date/time. The current time will be UTC-8 and the string given will ALWAYS be a past date/time.

If the time difference is less than one hour, then the function returns x Minutes Ago. If the time difference is greater than one hour, but is still the same day, it returns x Hours ago. If the time difference was yesterday the script returns Yesterday. If the date is any other day the script should return the day in the pattern MM/DD/YYYY (ie. 01/16/2011). Finally, if the date doesn't match the pattern above, it should return N/A.

Examples

Pretend the current date and time is 3:00 AM on 01/29/2013. Using the function would produce the following results.

<?php
    compare_time("01/29/2013 2:45 AM");
        //=> 15 Minutes Ago
    compare_time("01/29/2013 1:35 AM");
        //=> 1 Hour Ago
    compare_time("01/29/2013 1:00 AM");
        //=> 2 Hours Ago
    compare_time("01/28/2013 9:32 PM");
        //=> Yesterday
    compare_time("01/16/2013 1:34 PM");
        //=> 01/16/2013
    compare_time("02/15/2014");          // doesn't follow the pattern
        //=> N/A
?>
Tags
PHP

Crowdsource coding tasks.

3 Solutions

Winning solution

Solutuion for PHP 5.3

function compare_time($time) {
    $curDateTime = new DateTime();
    try {
        $dateTime = new DateTime($time);
    } catch (Exception $e) {
        return "N/A";
    }
    $interval = $curDateTime->diff($dateTime);
    $yesterday = new DateTime($curDateTime->format("Y-m-d"));
    $yesterday->sub(new DateInterval("P1D"));
    if ($yesterday->format("Y-m-d") == $dateTime->format("Y-m-d")) {
        return "Yesterday";
    }
    $daysInterval = $interval->format('%a');
    if ($daysInterval < 1) {
        $hoursInterval = $interval->format("%h");
        if ($hoursInterval < 1) {
            return $interval->format("%i minutes ago");
        } else {
            return $hoursInterval . " hours ago";
        }
    } else {
        return $dateTime->format("m/d/Y");
    }
}

Here you go (you'll need to change the timezones):

function compare_time($date)
{
  $date = DateTime::createFromFormat('m/d/Y g:i A', $date, new DateTimeZone('UTC'));

  if ($date !== false) {
    $difference = $date->diff($present = new DateTime('now', new DateTimeZone('UTC')), true);

    if (strncmp($date->format('Ymd'), $present->format('Ymd'), 8) === 0) {
      if ($difference->h > 0) {
        return sprintf('%u Hour%s ago', $difference->h, (($difference->h != 1) ? 's' : ''));
      }

      return sprintf('%u Minute%s ago', $difference->m, (($difference->m != 1) ? 's' : ''));
    }

    else if (($difference->d < 1) && ($difference->h < 24)) {
      return 'Yesterday';
    }

    return $date->format('m/d/Y');
  }

  return 'N/A';
}

var_dump(compare_time("01/29/2013 2:45 AM")); # 7 Hours ago
var_dump(compare_time("01/29/2013 1:35 AM")); # 8 Hours ago
var_dump(compare_time("01/29/2013 1:00 AM")); # 9 Hours ago
var_dump(compare_time("01/28/2013 9:32 PM")); # Yesterday
var_dump(compare_time("01/16/2013 1:34 PM")); # 01/16/2013
var_dump(compare_time("02/15/2014")); # N/A

I'm somewhat confused when you want it to return "Yesterday", perhaps you could explain it a bit better.

Sorry for not being clear, the function is supposed to return "Yesterday" if the $date is yesterday in relationship to the current date.
alex over 6 years ago
@alex: So, right now it's "2013-01-29 15:45", should the date "2013-01-28 14:00" be returned as "Yesterday" (even though the difference is greater than 24 hours)? If so, (($difference->d < 1) && ($difference->h < 24)) should be replaced by ($difference->d <= 1).
alixaxel over 6 years ago

2 suggestions (it's not really an answer, but it was too long for a comment):

  • Try storing your dates in Unix Time. This will make your life much easier because the dates are represented as a single integer. So manipulating dates is easier because you can just add or subtract the numbers, or use simple > / < conditionals to compare them. Also, this is a very common format for time-stamps, so many libraries support it.

  • Look into using client-side date manipulation libraries like Moment.js. By formatting dates on the client-side, there is no possibility for a page loaded hours ago (either because a user opened a tab and forgot about your page, or because of the browser caching your page) to confuse a user by displaying an old (and now incorrect) time difference... Which is probably why websites like Facebook and GitHub use this approach. Also, by keeping your pages closer to being static, you can make use of server-side caching, which can speed up your website significantly.

View Timeline