How to Display Human Readable Post Dates in WordPress

7 Comments

Human Readable Post Dates

After the URLs as sentences tutorial earlier this week, I thought the topic of human readable websites would be worth touching on again. This time, we’ll look at post dates.

While it’s dead simple to include post dates inside WordPress permalinks (WordPress does this in its default post permalink structure) it’s also helpful to keep the date listed within the post.

Instead of displaying dates like this:

Posted August 19, 2010

We’re going to display dates like this:

Posted yesterday

If you want to jump straight to the functionality, you can do that. Grab the Date in a Nice Tone Plugin, and use their template tag. But this is a tutorial, right? So let’s dig in and look at how this Plugin works.

Before looking at how this Plugin works, let’s think through it conceptually. Our end goal is to display a human readable post date that uses terms like yesterday and last month. So we’re going to need to build a PHP function that will do a few things:

  1. Find the current time.
  2. Find the time of the post.
  3. Find the difference between the two.
  4. If the difference equals x, display y.

It’s actually a pretty simple process. Let’s begin stepping through the wp-date-in-a-nice-tone.php file that comes with the Plugin. Feel free to download the Plugin from the link above and follow along.

The first few lines of the function look like this:

function wp_date_in_a_nice_tone() {

     $postTime = get_the_time("U");
     $currentTime = time();
     $timeDifference = $currentTime - $postTime;

     $minInSecs = 60;
     $hourInSecs = 3600;
     $dayInSecs = 86400;
     $monthInSecs = $dayInSecs * 31;
     $yearInSecs = $dayInSecs * 366;

This whole block of code sets up the variables for the rest of the function. First we get the time the post was published, using get_the_time("U");. This is a WordPress function that, along with the parameter provided by PHP, grabs the post’s date in seconds.

Next, the variable $currentTime is set to the current time, which is determined using the PHP function time();.

With the last line of the first block of code, the $timeDifference is found by subtracting the $postTime from the $currentTime. This gives us the difference, which we can use in the rest of the function to assign certain phrases to certain lengths of time.

     $minInSecs = 60;
     $hourInSecs = 3600;
     $dayInSecs = 86400;
     $monthInSecs = $dayInSecs * 31;
     $yearInSecs = $dayInSecs * 366;

This second block of PHP is simple, in that it’s assigning variables to lengths of time so that we don’t have to litter the function with so many numbers. We can’t refer to an hour as “an hour” within PHP, we have to refer to it as the number of seconds. So by creating the $hourInSecs variable, we can refer to it almost as conveniently.

     // if over 3 years
     if ($timeDifference > ($yearInSecs * 3)) {
          $dateWithNiceTone = "quite a long while ago...";

     // if over 2 years
     } else if ($timeDifference > ($yearInSecs * 2)) {
          $dateWithNiceTone = "over two years ago";

     . . .

     // if over 28 days ago
     } else if ($timeDifference > ($dayinSecs * 28)) {
          $dateWithNiceTone = "around a month ago";

     // if equal to or more than 8 days ago
     } else if ($timeDifference >= ($dayInSecs * 8)) {
          $dateWithNiceTone = "in the last month";

Finally, we get into the meat of the function; and it’s actually quite straightforward. Beginning with the oldest dates (in this case 3 years, though there’s no reason you couldn’t start it sooner), the time difference is checked against what would be the equivalent in 3 years of seconds. If that is the case, it sets the $dateWithNiceTone variable to “quite a long time ago…” and if that’s not the case, it continues to the next step. A pretty simple if…else if sequence.

Where this Plugin doesn’t have an administrative interface, you can see that it wouldn’t be difficult to change the words used, or to add in your own statement based on a new scenario.

If we wanted to show if a post was added yesterday, we could add this toward the bottom:

     // if equal to 24 hours or more
     } else if ($timeDifference > ($hourInSecs * 24)) {
          $dateWithNiceTone = "yesterday";

This is one of the statements that we added for WPCandy, except in our case we went with 18 rather than 24, because we found it to be more accurate in practice.

Finally, the Plugin echoes the variable:

     echo $dateWithNiceTone;

Which is, of course, to be expected.

I’m sure if you are interested in this functionality you will grab the Plugin. After all, that’s what I did. But hopefully now you not only use it, you also understand how it works. If you wanted to, perhaps you could write the function yourself now. While this is a simple Plugin with a simple purpose, having this experience will make it easier to understand, reverse engineer, and truly understand more complicated Plugins in the future.

7 thoughts on “How to Display Human Readable Post Dates in WordPress

    • That’s one way to go about it, for sure. I like this method because it gives more control over what exactly is said at each step (1 day ago vs. yesterday, for example). But where not that much control is needed, you’re right, that’s a simple way to go.

      • Wow, that function has been around since WordPress 1.5 – over five years! I wonder if it would be a good candidate for some core improvements, to allow for the sort of customization you’re providing here?

        Seems somewhat of a waste to have a plugin just to do in a slightly different manner the same thing that a core function does. Maybe I’ll go have a look-see under the hood of human_time_diff()…

  1. Cool thing. I’d add the real date in a span title however, just so that you can hover the “a few days ago” bit and see how many days exactly.

  2. Hello,
    I know this is a little off topic but since you are discussing times and dates may some Can help me?

    I have been up for a day and half trying figure this out. I am a newbie so i’m totally self taught. with that being said can someone tell me how get this code to work? I would like it so that once the event date has passed the event no longer shows. I want the events to be sorted by the custom event_date field and then not be shown once the event_date has passed.
    I enter the event_date format 03/14/2011
    Below is the code is have. I’m using it and a function for all the archive category pages. Could someone please please help me? The events sort correctly but they are still showing up after the event_date has passed.
    —————————————–

    add_filter('posts_join', 'new_join' );
    function new_join($pjoin){
    if(is_category()){
    global $wpdb;
    $pjoin .= "LEFT JOIN (
    SELECT *
    FROM $wpdb->postmeta
    WHERE meta_key = 'event_date'
    AND STR_TO_DATE(meta_value,'%m/%d/%Y %H:%i:%s') >= CURDATE() ) AS metasort
    ON $wpdb->posts.ID = metasort.post_id";
    }
    return ($pjoin);
    }

    add_filter('posts_orderby', 'new_order' );
    function new_order( $orderby ){
    global $wpdb;
    if(is_category()){
    $orderby = "metasort.meta_value, '%m/%d/%Y %H:%i:%s' ASC";
    }

    return $orderby;
    }

  3. How about, if it’s “more than a week”, it will display the original date? (for example, “10 days ago” would become “12th July 2010″

Leave a Reply

Please note that WPCandy is a moderated community.

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>