Fuzzier (human-friendly) timestamps with Drupal 6.x

I set up super-sweet fuzzy “submitted by” timestamps on my blog a couple of days ago. They’re quite a bit easier to grok at a glance, and they show the full date when you hover over them.

Drupal 6.x makes tweaks like this easy. Here’s how you can do it too:

Open up your theme’s template.php file. If you’re using a stock theme, copy the theme from Drupal core into your site’s themes folder before editing anything.

Add these three functions:

<?php
function _fuzzy_delta($to, $from = null, $granularity = 1) {
    $times = array(
        'year'   => 31536000,
        'month'  => 2592000,
        'week'   => 604800,
        'day'    => 86400,
        'hour'   => 3600,
        'minute' => 60,
        'second' => 1
    );
 
    if ($from === null) $from = time();
    $secs = abs($from - $to);
 
    if ($secs == 0) return '0 seconds';
 
    $count = 0;
    $time = '';
 
    foreach ($times as $name => $value) {
        if ($secs >= $value) {
            $slice = floor($secs / $value);
            $time .= $slice . ' ' . $name;
            if (($slice != 1)) $time .= 's';
 
            $secs = $secs % $value;
            $count++;
            if ($count > $granularity - 1 || $secs == 0) break;
            else $time .= ', ';
        }
    }
 
    return $time;
}

function phptemplate_node_submitted($node) {
    return t('posted by !username <span title="@long_date">@ago ago</span>',
        array(
            '!username' => theme('username', $node),
            '@long_date' => format_date($node->created, 'long'),
            '@ago' => _fuzzy_delta($node->created)
        )
    );
}

function phptemplate_comment_submitted($comment) {
    $node = node_load($comment->nid);
    return t('comment by !username <span title="@date">@later later</span>',
        array(
            '!username' => theme('username', $comment),
            '@date' => format_date($comment->timestamp, 'long'),
            '@later' => _fuzzy_delta($comment->timestamp, $node->created),
        )
    );
}

If you want comments to use “ago” formatting instead of “later”, use this version of phptemplate_comment_submitted instead:

<?php
function phptemplate_comment_submitted($comment) {
    return t('comment by !username <span title="@date">@ago ago</span>',
        array(
            '!username' => theme('username', $comment),
            '@date' => format_date($comment->timestamp, 'long'),
            '@ago' => _fuzzy_delta($comment->timestamp),
        )
    );
}

Now check out your hot new datestamps!

Note: For my theme, I had to change the comment.tpl.php template file. You might have to change that and/or your node template files. Here’s the chunk I had to add to mine:

<div class="submitted"><?php print theme('comment_submitted', $comment); ?></div>

Enjoy.