I recently required a pretty-date function to format some twitter dates; I knew there were already quite a few of these floating around the net; but I wanted to give it a try myself:

Regular pretty-date:

Note: Remember, pretty-dates are not meant to be accurate; they’re meant to be “pretty” – once you go past months it does get pretty inaccurate; afterall, logically, when we’re talking about time difference, what is a month? 30 days? Four weeks? The amount of days in a year divided by the amount of months in a year? The same dilemma occurs with larger measures like years; – if I say “one year ago”, are you thinking 365 days? yes? – well then 5 years ago would have to be [365*5] days, right? Nope, not if you assume one of those years is a leap year!

var niceTime = (function() {
 
    var ints = {
        second: 1,
        minute: 60,
        hour: 3600,
        day: 86400,
        week: 604800,
        month: 2592000,
        year: 31536000
    };
 
    return function(time) {
 
        time = +new Date(time);
 
        var gap = ((+new Date()) - time) / 1000,
            amount, measure;
 
        for (var i in ints) {
            if (gap > ints[i]) { measure = i; }
        }
 
        amount = gap / ints[measure];
        amount = gap > ints.day ? (Math.round(amount * 100) / 100) : Math.round(amount);
        amount += ' ' + measure + (amount > 1 ? 's' : '') + ' ago';
 
        return amount;
    };
 
})();

Usage:

niceTime( 1 );                                  // => "39.57 years ago"
niceTime( "Sun Mar 01 20:20:02 +0000 2009" );   // => "4.65 months ago"
niceTime( "July 19, 2009 12:06:00" );           // => "26 seconds ago"

I then decided to take it a step further and create a recursive version that keeps going until it hits the smallest measure of time available:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
var prettyTimeDiff = (function() {
 
    var ints = {
        second: 1,
        minute: 60,
        hour: 3600,
        day: 86400,
        week: 604800,
        month: 2592000,
        year: 31536000,
        decade: 315360000
    };
 
    return function(aTime, bTime) {
 
        aTime = +new Date(aTime);
        bTime = bTime === undefined ? +new Date() : +new Date(bTime);
 
        var timeGap = Math.abs(bTime - aTime) / 1000,
            amount, measure, remainder, smallest;
 
        for (var i in ints) {
            if (timeGap > ints[i] && ints[i] > (ints[measure] || 0)) {
                measure = i;
            }
            if (!smallest || ints[i] < smallest) {
                smallest = ints[i];
            }
        }
 
        amount = Math.floor(timeGap / ints[measure]);
 
        if (timeGap > 31536000) {
            /* Handle leap years */
            timeGap -= Math.floor(ints[measure] * amount / 31536000 / 4) * 86400;
        }
 
        amount += ' ' + measure  + (amount > 1 ? 's' : '');
 
        remainder = timeGap % ints[measure];
 
        if (remainder >= smallest) {
            amount += ', ' + arguments.callee( +new Date() - remainder*1000 );
        }
 
        return amount;
    };
 
})();

I decided to call it prettyTimeDiff as it can actually take two dates and then will give you the difference between them in pretty-format. If you only pass one date then it’ll assume you want to compare it to today.

Usage:

prettyTimeDiff( 0 );
    // => "3 decades, 9 years, 6 months, 2 weeks, 4 days, 51 minutes, 25 seconds"
 
prettyTimeDiff( "July 1, 2005", "July 2, 2006" );
    // => "1 year, 24 hours"
 
prettyTimeDiff( 0, 5000 );
    // => "5 seconds"
 
prettyTimeDiff( "Sun Mar 01 20:20:02 +0000 2009" ) + ' ago';
    // => "4 months, 2 weeks, 4 days, 37 minutes, 49 seconds ago"

You can limit what units it uses to measure time; for example, if you don’t want decades then just delete ints['decade']. The function will use whatever it can; so, if you only want it to measure time in minutes, years and decades then simply comment-out/remove all the other units:

var ints = {
    //second: 1,
    minute: 60,
    //hour: 3600,
    //day: 86400,
    //week: 604800,
    //month: 2628000,
    year: 31536000,
    decade: 315360000
};

An example with the above adjustment:

prettyTimeDiff( "January 19, 1988" )
    // => "2 decades, 1 year, 262873 minutes"

It’s quite quick so could easily be used within any number of applications; for example, if you ever needed to countdown to the year 3000!