David Corbacho

"Time ago" date format in Drupal

The time ago format it's known as fuzzy timestamp, and they were popularized some years ago specially by Facebook and Twitter.

At first you may think PHP could do this work, and even Drupal has a core format_interval function that allows you to do:

$timeago = format_interval(time() - $node->created, 1) . ' ' . t('ago')'; 

But in many cases this is no the most suitable way to do it, for two main reasons:

  • Time zone. The fuzzy timestamp needs to be relative to the user time zone, not the server one.
  • Cache. If you use any server-side cache solution, the information "2 minutes ago" won't be true for long time.

There is a neat solution to solve this task: jQuery TimeAgo plugin. Since Drupal has already jQuery in core, it's quite easy to implement and will bring these benefits:

  • It uses the client time zone based on JavaScript Date().
  • Time is always correct from user perspective, even without refreshing. For example "Some seconds ago" will change to "about a minute ago" as time passes by.
  • Easy to customize, including i18n settings.
  • Handles both microformat and HTML time tag.
  • Correct daylight timezone. In Drupal 6 the daylight timezone is not handle right when using format_date. See this issue.

Implementation.

Now that I have convinced you, let's integrate jQuery TimeAgo with Drupal to format the submitted dates in the nodes, using the hook_preprocess_node. Note that I'm using the American date style: month day, year for example Nov 25th, 2011 for the normal style. This will be visible when hovering over and also when Javascript is disabled.

/**
 * Format date implementing hook_preprocess_node().
 */
function YOURTHEME_preprocess_node(&$vars) {
  $node = $vars['node'];
  $vars['date'] = format_date($node->created, 'custom', 'M jS, Y');
  $vars['time_ago'] = format_date($node->created, 'custom', 'c'); // 'c' is the ISO 8601 date format. Since PHP 5
}

Then in the node.tpl.php template of your theme, place this wherever you want:

<abbr class="timeago" title="<?php print $time_ago; ?>"><?php print $date; ?></abbr>

Add the JavaScript library like usual, in your theme .info file.

Notes.

  • It wouldn't be difficut to create a module out of it, integrating the library and its i18n options with with Drupal behaviors, t() and Date module.
  • Note that jQuery Timeago is MIT Licensed.
  • While writing this post I found that someone created another Javascript solution called moment.js (They gave credit to the Timeago plugin).