You may have noticed the cool little featured here on my personal blog where, instead of showing the date of the current WordPress post in the typical format, I’m showing it in the Twitter-like “time ago” format. In this tutorial I’ll show you exactly how I’m doing it and how you can incorporate the same thing into your WordPress theme.

Background Information

When I was designing this blog, I was really trying to get into the spirit of this whole micro-blogging meets-regular blog-meets Tumblr feel and also utilize WordPress post formats (introduced in WordPress 3.1). So, I thought it would totally fit the style of it all to somehow incorporate the Twitter-like format of showing when each post was published. For me personally, I can never keep track of what month or even what year it is sometimes. I guess the more time I spend on the Internet, the more fried my brain becomes. So, for me, it’s much quicker to comprehend if I can see that a post was published “3 years ago,” opposed to seeing a date and trying to do quick math in my head.

I assumed this would be something many people are doing and that I’d be able to quickly find a code snippet that I could copy and paste into my WordPress theme, but I was definitely wrong on that one. I came across several sites all referencing how to accomplish this in a similar way, but all weren’t really ideal for me.

Most of the examples I found all utilized the built-in WordPress function, human_time_diff. It was super easy to just take the publish date of a post, run it through this function, and display something similar to what I wanted. The problem though was that this WordPress function will only return this “human time difference” in the number of days. So for example after a month, you’d end up with something like “32 days ago,” and after a year, “165 days ago.”

I’m not really sure why WordPress would have the human_time_diff function in there with such a mediocre result. I think the function is more intended to be used for a short period of time. Either way, it’s even been brought up over on WordPress trac, but I guess they didn’t care too much about improving it.

However, one of the people that commented on that particular WordPress trac ticket actually linked to a function found in BuddyPress that does exactly what I was wanting to do.

So, it was BuddyPress’s bp_core_time_since function that inevitably lead me to my answer. I took their function and adapted it into something that could be used with the standard WordPress loop by hooking into WordPress’s the_time function.

The idea of adding it as a filter to WordPress’s the_time function I got from Lam Nguyen on his post:

Quick Tip: Display Timeago For WordPress If Less Than 24 Hours

I guess the chunk of the title of that post, “if less than 24 hours” pretty much sums up why using the human_time_diff WordPress function won’t work for what I was wanting to do.

The Code

The code I’m about to show is a little long, but it will allow you to display when your posts were published in a nice, user-friendly format that increments how the image below shows:

Step 1

First, copy this code into your functions.php file (or wherever in your theme you want – advanced theme authors generally will organize their functions in more files that just the functions.php).

function themeblvd_time_ago() {
	
	global $post;
	
	$date = get_post_time('G', true, $post);
	
	/**
	 * Where you see 'themeblvd' below, you'd
	 * want to replace those with whatever term
	 * you're using in your theme to provide
	 * support for localization.
	 */ 
	
	// Array of time period chunks
	$chunks = array(
		array( 60 * 60 * 24 * 365 , __( 'year', 'themeblvd' ), __( 'years', 'themeblvd' ) ),
		array( 60 * 60 * 24 * 30 , __( 'month', 'themeblvd' ), __( 'months', 'themeblvd' ) ),
		array( 60 * 60 * 24 * 7, __( 'week', 'themeblvd' ), __( 'weeks', 'themeblvd' ) ),
		array( 60 * 60 * 24 , __( 'day', 'themeblvd' ), __( 'days', 'themeblvd' ) ),
		array( 60 * 60 , __( 'hour', 'themeblvd' ), __( 'hours', 'themeblvd' ) ),
		array( 60 , __( 'minute', 'themeblvd' ), __( 'minutes', 'themeblvd' ) ),
		array( 1, __( 'second', 'themeblvd' ), __( 'seconds', 'themeblvd' ) )
	);

	if ( !is_numeric( $date ) ) {
		$time_chunks = explode( ':', str_replace( ' ', ':', $date ) );
		$date_chunks = explode( '-', str_replace( ' ', '-', $date ) );
		$date = gmmktime( (int)$time_chunks[1], (int)$time_chunks[2], (int)$time_chunks[3], (int)$date_chunks[1], (int)$date_chunks[2], (int)$date_chunks[0] );
	}
	
	$current_time = current_time( 'mysql', $gmt = 0 );
	$newer_date = strtotime( $current_time );

	// Difference in seconds
	$since = $newer_date - $date;

	// Something went wrong with date calculation and we ended up with a negative date.
	if ( 0 > $since )
		return __( 'sometime', 'themeblvd' );

	/**
	 * We only want to output one chunks of time here, eg:
	 * x years
	 * xx months
	 * so there's only one bit of calculation below:
	 */

	//Step one: the first chunk
	for ( $i = 0, $j = count($chunks); $i < $j; $i++) {
		$seconds = $chunks[$i][0];

		// Finding the biggest chunk (if the chunk fits, break)
		if ( ( $count = floor($since / $seconds) ) != 0 )
			break;
	}

	// Set output var
	$output = ( 1 == $count ) ? '1 '. $chunks[$i][1] : $count . ' ' . $chunks[$i][2];
	

	if ( !(int)trim($output) ){
		$output = '0 ' . __( 'seconds', 'themeblvd' );
	}
	
	$output .= __(' ago', 'themeblvd');
	
	return $output;
}

// Filter our themeblvd_time_ago() function into WP's the_time() function
add_filter('the_time', 'themeblvd_time_ago');

View this code on Pastie: http://pastie.org/1785073

Make sure to take note of that last add_filter part on the very last line. That’s an important part because that’s where our long function actually gets tied into WordPress. Without it, we just have a random function sitting there, not doing anything!

Step 2

So, now that you’ve copied the above code into your theme, it’s super easy to utilize; simply use the_time() in your theme file, and it will display in our new and improved “time ago” format.

Here’s a really simple example of standard WordPress loop:

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

	<div class="entry">

		<h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
	
		<small><?php the_time(); ?> by <?php the_author_posts_link(); ?></small>
		
		<?php the_content(); ?>
		
	</div><!-- .entry (end) -->
	
<?php endwhile; else: ?>

	<p>Sorry, no posts matched your criteria.</p>

<?php endif; ?>

Where you see “the_time” function being used in the snippet above, it will display as we want. It’s possible in your theme you’re already using the_time function, and so you may not even have to change anything. It will just be working from only doing step 1.

One thing to note though is that it’s very common when using the_time function within your WordPress loop, that you will have designated a format to be used within the_time function like this:

<?php the_time('F j, Y'); ?>

Or something more like this, which is how you should have be doing it before (especially if this is commercial theme you’re creating):

<?php the_time( get_option('date_format') ); ?>

However, for this function to work properly now the way we’ve modified it, it would be best to call the_time function within our loop with no format simply like this:

<?php the_time(); ?>