Let's say I've got two strings in JavaScript:
var date1 = '2008-10-03T20:24Z'
var date2 = '2008-10-04T12:24Z'
How would I e to a result like so:
'4 weeks ago'
or
'in about 15 minutes'
(should support past and future).
There are solutions out there for the past diffs, but I've yet to find one with support for future time diffs as well.
These are the solutions I tried:
John Resig's Pretty Date and Zach Leatherman's modification
Bonus points for a jQuery solution.
Let's say I've got two strings in JavaScript:
var date1 = '2008-10-03T20:24Z'
var date2 = '2008-10-04T12:24Z'
How would I e to a result like so:
'4 weeks ago'
or
'in about 15 minutes'
(should support past and future).
There are solutions out there for the past diffs, but I've yet to find one with support for future time diffs as well.
These are the solutions I tried:
John Resig's Pretty Date and Zach Leatherman's modification
Bonus points for a jQuery solution.
Share Improve this question edited Oct 6, 2008 at 17:41 Pete Karl II 4,3003 gold badges23 silver badges27 bronze badges asked Oct 3, 2008 at 21:08 Nick SergeantNick Sergeant 38.2k12 gold badges38 silver badges44 bronze badges 2- You already have a solution for past diffs? Swap the dates over, solve, strip the " ago" from the end, prepend "In about ". Done. ;) – moonshadow Commented Oct 3, 2008 at 21:15
- just posted solutions I tried - future dates don't work so well – Nick Sergeant Commented Oct 3, 2008 at 21:17
2 Answers
Reset to default 7Looking at the solutions you linked... it is actually as simple as my frivolous ment!
Here's a version of the Zach Leatherman code that prepends "In " for future dates for you. As you can see, the changes are very minor.
function humane_date(date_str){
var time_formats = [
[60, 'Just Now'],
[90, '1 Minute'], // 60*1.5
[3600, 'Minutes', 60], // 60*60, 60
[5400, '1 Hour'], // 60*60*1.5
[86400, 'Hours', 3600], // 60*60*24, 60*60
[129600, '1 Day'], // 60*60*24*1.5
[604800, 'Days', 86400], // 60*60*24*7, 60*60*24
[907200, '1 Week'], // 60*60*24*7*1.5
[2628000, 'Weeks', 604800], // 60*60*24*(365/12), 60*60*24*7
[3942000, '1 Month'], // 60*60*24*(365/12)*1.5
[31536000, 'Months', 2628000], // 60*60*24*365, 60*60*24*(365/12)
[47304000, '1 Year'], // 60*60*24*365*1.5
[3153600000, 'Years', 31536000], // 60*60*24*365*100, 60*60*24*365
[4730400000, '1 Century'], // 60*60*24*365*100*1.5
];
var time = ('' + date_str).replace(/-/g,"/").replace(/[TZ]/g," "),
dt = new Date,
seconds = ((dt - new Date(time) + (dt.getTimezoneOffset() * 60000)) / 1000),
token = ' Ago',
prepend = '',
i = 0,
format;
if (seconds < 0) {
seconds = Math.abs(seconds);
token = '';
prepend = 'In ';
}
while (format = time_formats[i++]) {
if (seconds < format[0]) {
if (format.length == 2) {
return (i>1?prepend:'') + format[1] + (i > 1 ? token : ''); // Conditional so we don't return Just Now Ago
} else {
return prepend + Math.round(seconds / format[2]) + ' ' + format[1] + (i > 1 ? token : '');
}
}
}
// overflow for centuries
if(seconds > 4730400000)
return Math.round(seconds / 4730400000) + ' Centuries' + token;
return date_str;
};
Heh - I actually wrote a function to do this exact thing yesterday (and it's not on this puter so I'll just have to try to remember it)
I extended the Date prototype class, but this could quite easily just be put into a regular function.
Date.prototype.toRelativeTime = function(otherTime) {
// if no parameter is passed, use the current date.
if (otherTime == undefined) otherTime = new Date();
var diff = Math.abs(this.getTime() - otherTime.getTime()) / 1000;
var MIN = 60, // some "constants" just
HOUR = 3600, // for legibility
DAY = 86400
;
var out, temp;
if (diff < MIN) {
out = "Less than a minute";
} else if (diff < 15 * MIN) {
// less than fifteen minutes, show how many minutes
temp = Math.round(diff / MIN);
out = temp + " minute" + (temp == 1 ? "" : "s");
// eg: 12 minutes
} else if (diff < HOUR) {
// less than an hour, round down to the nearest 5 minutes
out = (Math.floor(diff / (5 * MIN)) * 5) + " minutes";
} else if (diff < DAY) {
// less than a day, just show hours
temp = Math.round(diff / HOUR);
out = temp + " hour" + (temp == 1 ? "" : "s");
} else if (diff < 30 * DAY) {
// show how many days ago
temp = Math.round(diff / DAY);
out = temp + " day" + (temp == 1 ? "" : "s");
} else if (diff < 90 * DAY) {
// more than 30 days, but less than 3 months, show the day and month
return this.getDate() + " " + this.getShortMonth(); // see below
} else {
// more than three months difference, better show the year too
return this.getDate() + " " + this.getShortMonth() + " " + this.getFullYear();
}
return out + (this.getTime() > otherTime.getTime() ? " from now" : " ago");
};
Date.prototype.getShortMonth = function() {
return ["Jan", "Feb", "Mar",
"Apr", "May", "Jun",
"Jul", "Aug", "Sep",
"Oct", "Nov", "Dec"][this.getMonth()];
};
// sample usage:
var x = new Date(2008, 9, 4, 17, 0, 0);
alert(x.toRelativeTime()); // 9 minutes from now
x = new Date(2008, 9, 4, 16, 45, 0, 0);
alert(x.toRelativeTime()); // 6 minutes ago
x = new Date(2008, 11, 1); // 1 Dec
x = new Date(2009, 11, 1); // 1 Dec 2009