Time Ago: How to Display Publish Dates as Time Since Posted

Share this article

It’s common to present dates on the Web in a format such as Published on September 12th, 2015, or 09/12/2015, 09:41:23 and 2015-09-12.

Each of these examples tells the full date and/or time of some kind of activity – be it a published article, or a reader comment, or perhaps an uploaded video.

Date formats like this might seem perfectly reasonable. After all, they’re informative and human-readable! Well yes, but “human-readable” doesn’t necessary mean users will readily be able to understand how recently the activity has occurred. The Web is a fast-moving place, and giving your content a sense of freshness could be the key to engaging with your audience! So, let’s look at how we could improve on these common date formats.

A Little Trick

Once again, let’s say you have stumbled on a post that was actually published just a couple of minutes ago, but the subheading of the post states this:

Published on September 12th, 2016

… or this:

Published on 2016-09-12, 09:41:23

The problem with these messages is that they don’t communicate the feeling that your website has just been updated or that you do that very often. So, surely it be more inviting – and much clearer – to present the time this way:

Published 2 minutes ago

Seen this many times before? But how many of you have built this into your projects? Take Facebook for example: what would it look like if they presented the dates for the latest content as in my first example? Compare the left and right columns in the following image:

timestamp formats compared

The left column’s dates aren’t that attractive, are they? I’ll wager the right hand examples are more appealing to you. Knowing that the content is fresh is very important – especially on the social networks, where people are more likely to ignore content that’s old or not clearly timestamped.

Printing Better Dates

In order to present better dates, you’ll need some server-side scripting, and I’ll use PHP for this demo. I created a tiny function called time_ago(), as shown here:

<?php

    define( TIMEBEFORE_NOW,         'now' );
    define( TIMEBEFORE_MINUTE,      '{num} minute ago' );
    define( TIMEBEFORE_MINUTES,     '{num} minutes ago' );
    define( TIMEBEFORE_HOUR,        '{num} hour ago' );
    define( TIMEBEFORE_HOURS,       '{num} hours ago' );
    define( TIMEBEFORE_YESTERDAY,   'yesterday' );
    define( TIMEBEFORE_FORMAT,      '%e %b' );
    define( TIMEBEFORE_FORMAT_YEAR, '%e %b, %Y' );

    function time_ago( $time )
    {
        $out    = ''; // what we will print out
        $now    = time(); // current time
        $diff   = $now - $time; // difference between the current and the provided dates

        if( $diff < 60 ) // it happened now
            return TIMEBEFORE_NOW;

        elseif( $diff < 3600 ) // it happened X minutes ago
            return str_replace( '{num}', ( $out = round( $diff / 60 ) ), $out == 1 ? TIMEBEFORE_MINUTE : TIMEBEFORE_MINUTES );

        elseif( $diff < 3600 * 24 ) // it happened X hours ago
            return str_replace( '{num}', ( $out = round( $diff / 3600 ) ), $out == 1 ? TIMEBEFORE_HOUR : TIMEBEFORE_HOURS );

        elseif( $diff < 3600 * 24 * 2 ) // it happened yesterday
            return TIMEBEFORE_YESTERDAY;

        else // falling back on a usual date format as it happened later than yesterday
            return strftime( date( 'Y', $time ) == date( 'Y' ) ? TIMEBEFORE_FORMAT : TIMEBEFORE_FORMAT_YEAR, $time );
    }

?>

Let’s look at some details of this code.

  • The only argument you must provide is $time, and it’s a date in Unix Timestamp – such as time_ago( 1442082961 ).
  • Examples of what the function will return in respect of the $time passed:
    • now – if it happened less than 60 seconds ago (TIMEBEFORE_NOW)
    • 3 minutes ago – if less than 60 minutes ago (TIMEBEFORE_MINUTE(S))
    • 8 hours ago – if less than 24 hours ago (TIMEBEFORE_HOUR(S))
    • yesterday – if less than 48 hours ago (TIMEBEFORE_YESTERDAY)
    • 12 Sep – if more than 48 hours and happened this year (TIMEBEFORE_FORMAT)
    • 12 Sep, 2015 – if happened not this year (TIMEBEFORE_FORMAT_YEAR).
  • The PHP definitions are for separating the config-like data from the function code (it would be a good practice to put all of the define() occurrences into a config file and the function in helpers file).
  • {num} in definitions are replaced with actual numbers (minutes or hours).
  • I use strftime() instead of date() to avoid language/locale issues.

So, for example, if you want to get this onto your WordPress site, you’d simply write this:

<?=time_ago( get_the_time( 'U' ) )?>

Or if it was some other hypothetical CMS:

<?=time_ago( $post->date_created )?>

Or the static way:

<?=time_ago( 1447571705 )?>

Accessibility & Usability

There’s a specific HTML element that you should use for presenting dates: <time>. In our case, when using the time_ago function, the value of the time element is not always in a valid date format (like yesterday or 3 minutes ago). Therefore, you should also provide a fallback value by using [datetime] attribute:

Published <time 
    datetime="<?=date( 'Y-m-d', $time )?>" 
    title="<?=strftime( date( 'Y', $time ) == 
        date( 'Y' ) ? TIMEBEFORE_FORMAT : TIMEBEFORE_FORMAT_YEAR, $time )?>">
    <?=time_ago( $time )?>
    </time>

This would result in better accessibility, for example:

Published <time datetime="2015-09-12" title="September 12">3 minutes ago</time>

Did you spot the [title] attribute? It’s a tiny usability improvement: putting the cursor over date text shows a message presented in the title attribute. That’s for the users who, for some reason, were looking for the “real” dates. Here’s a little CSS trick to beef up the feeling that there is something more:

time[title]
{
    cursor: help;
}

CSS help cursor

JavaScript Enhancement

There’s one more thing we can do! Have you noticed that Facebook also increments the dates in real time? Just watch at 3 mins for a minute and it will turn into 4 mins and so on. So, there are types of websites were this works out as a really nice enhancement. It wouldn’t be useful on an article post like this, but It’s perfect on a site like Readerrr:

<time data-time="<?=$time?>" ...

Finally, we need to convert the PHP code into a JavaScript equivalent. I’ve done this for you in vanilla JS (though a jQuery version is available as well). The script walks through each time[data-time] element once every minute (setTimeout( updateDates, 1000 * 60 )) and updates the values:

// ...
var elements    = document.querySelectorAll( 'time[data-time]' ),
    updateDates = function()
    {
        Array.prototype.forEach.call( elements, function( entry )
        {
            var out = '';
            // ...
            entry.textContent = out;
        });
        setTimeout( updateDates, 1000 * 60 );
    };
setTimeout( updateDates, 1000 * 60 );
// ...

A JavaScript demo

Online Demo and Code Download

You can check out an online demo of the above code or download the full demo code.

One more thing

In the examples above, the full date is presented if the activity has occurred three or more days ago. But it’s quite easy to extend the script for presenting the time in the ways like 5 days ago, 2 weeks ago and 1 month ago, and so on:

// ...

define( TIMEBEFORE_DAYS,    '{num} days ago' );
define( TIMEBEFORE_WEEK,    '{num} week ago' );
define( TIMEBEFORE_WEEKS,   '{num} weeks ago' );
define( TIMEBEFORE_MONTH,   '{num} month ago' );
define( TIMEBEFORE_MONTHS,  '{num} months ago' );

function time_before( $time )
{
    // ...

    elseif( $diff < 3600 * 24 * 7 )
        return str_replace( '{num}', round( $diff / ( 3600 * 24 ) ), TIMEBEFORE_DAYS );

    elseif( $diff < 3600 * 24 * 7 * 4 )
        return str_replace( '{num}', ( $out = round( $diff / ( 3600 * 24 * 7 ) ) ), $out == 1 ? TIMEBEFORE_WEEK : TIMEBEFORE_WEEKS );

    elseif( $diff < 3600 * 24 * 7 * 4 * 12 )
        return str_replace( '{num}', ( $out = round( $diff / ( 3600 * 24 * 7 * 4 ) ) ), $out == 1 ? TIMEBEFORE_MONTH : TIMEBEFORE_MONTHS );

    else
        // ...
}

Wrap Up

User experience and satisfaction is in details. Sometimes a simple detail – such as a dynamic date format – is enough to make our websites a little bit better.

So, what do you think of this solution? Would you consider using it on your next project? Do you have any questions about it? Please let me know in the comments.

By the way, I hope somebody can tell Instagram people that 122w isn’t cool, and that 2.4yrs would be much easier to understand. That would be better, wouldn’t it?

Frequently Asked Questions (FAQs) about Counting the ‘Ago’ Time

How does the ‘ago’ time function work in JavaScript?

The ‘ago’ time function in JavaScript is a way to display the time elapsed since a particular event occurred. It uses the Date object to calculate the difference between the current time and the time of the event. This difference is then converted into seconds, minutes, hours, days, weeks, or years, depending on the magnitude of the difference. The result is a string that represents the elapsed time in a human-readable format, such as “5 minutes ago” or “2 days ago”.

How can I implement the ‘ago’ time function in my web application?

To implement the ‘ago’ time function in your web application, you need to create a JavaScript function that takes a Date object as input and returns a string representing the elapsed time. This function should calculate the difference between the current time and the input date, convert this difference into the appropriate units, and format the result as a string. You can then call this function whenever you need to display the ‘ago’ time.

What are the benefits of using the ‘ago’ time function?

The ‘ago’ time function provides a more intuitive and user-friendly way to display time information. Instead of showing the exact date and time of an event, which can be difficult to interpret and compare, the ‘ago’ time function shows the elapsed time in a format that is easy to understand and relate to. This can enhance the user experience and make your web application more engaging and interactive.

Can the ‘ago’ time function handle future dates?

Yes, the ‘ago’ time function can handle future dates. If the input date is later than the current date, the function will calculate the time until the event instead of the time since the event. The result will be a string that represents the remaining time in a human-readable format, such as “in 5 minutes” or “in 2 days”.

How can I customize the ‘ago’ time function to suit my needs?

The ‘ago’ time function is highly customizable. You can modify the function to use different units of time, different formats for the output string, or different rules for rounding the elapsed time. You can also add support for different languages or locales, if needed. By tweaking the function, you can make it fit perfectly with the design and functionality of your web application.

Is the ‘ago’ time function compatible with all browsers?

The ‘ago’ time function is based on standard JavaScript features, so it should be compatible with all modern web browsers. However, it’s always a good idea to test your code on different browsers and platforms to ensure that it works correctly and consistently.

Can the ‘ago’ time function handle time zones?

Yes, the ‘ago’ time function can handle time zones. The function uses the Date object, which automatically takes into account the time zone of the user’s device. This means that the ‘ago’ time will be accurate regardless of the user’s location or time zone.

How can I debug the ‘ago’ time function if it’s not working correctly?

If the ‘ago’ time function is not working correctly, you can use the console.log() method to print out the input date, the current date, and the calculated difference. This will help you identify any errors or inconsistencies in the function. You can also use the debugger tool in your browser’s developer tools to step through the function and inspect its behavior in detail.

Can I use the ‘ago’ time function in a mobile app?

Yes, you can use the ‘ago’ time function in a mobile app. JavaScript is a versatile language that can be used in many different environments, including mobile apps. The function should work the same way in a mobile app as it does in a web application.

How can I optimize the performance of the ‘ago’ time function?

To optimize the performance of the ‘ago’ time function, you can use techniques such as memoization or caching. These techniques can reduce the number of calculations that the function needs to perform, making it faster and more efficient. You can also minimize the number of times the function is called by updating the ‘ago’ time only when necessary, rather than on every page load or every second.

Osvaldas ValutisOsvaldas Valutis
View Author

Osvaldas is a web designer who thinks in code and is a creator of Readerrr. He also writes about website design on development on his blog. Osvaldas is based in Klaipeda, Lithuania.

datedatetimeRalphMtimestamp
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week