Javascript timestamp to relative time
Update April 4, 2021:
I've converted the below code to a node package. Here's the repository.
Intl.RelativeTimeFormat - Native API
[✔] (Dec' 18) a Stage 3 proposal, and already implemented in Chrome 71
[✔] (Oct' 20) at Stage 4 (finished), and ready for inclusion in the formal ECMAScript standard
// in miliseconds
var units = {
year : 24 * 60 * 60 * 1000 * 365,
month : 24 * 60 * 60 * 1000 * 365/12,
day : 24 * 60 * 60 * 1000,
hour : 60 * 60 * 1000,
minute: 60 * 1000,
second: 1000
}
var rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' })
var getRelativeTime = (d1, d2 = new Date()) => {
var elapsed = d1 - d2
// "Math.abs" accounts for both "past" & "future" scenarios
for (var u in units)
if (Math.abs(elapsed) > units[u] || u == 'second')
return rtf.format(Math.round(elapsed/units[u]), u)
}
// test-list of dates to compare with current date
[
'10/20/1984',
'10/20/2015',
+new Date() - units.year,
+new Date() - units.month,
+new Date() - units.day,
+new Date() - units.hour,
+new Date() - units.minute,
+new Date() + units.minute*2,
+new Date() + units.day*7,
]
.forEach(d => console.log(
new Date(d).toLocaleDateString(),
new Date(d).toLocaleTimeString(),
'(Relative to now) →',
getRelativeTime(+new Date(d))
))
Intl.RelativeTimeFormat is available by default in V8 v7.1.179 and Chrome 71. As this API becomes more widely available, you’ll find libraries such as Moment.js, Globalize, and date-fns dropping their dependency on hardcoded CLDR databases in favor of the native relative time formatting functionality, thereby improving load-time performance, parse- and compile-time performance, run-time performance, and memory usage.
Here is the exact mimic of twitter time ago without plugins:
function timeSince(timeStamp) {
var now = new Date(),
secondsPast = (now.getTime() - timeStamp) / 1000;
if (secondsPast < 60) {
return parseInt(secondsPast) + 's';
}
if (secondsPast < 3600) {
return parseInt(secondsPast / 60) + 'm';
}
if (secondsPast <= 86400) {
return parseInt(secondsPast / 3600) + 'h';
}
if (secondsPast > 86400) {
day = timeStamp.getDate();
month = timeStamp.toDateString().match(/ [a-zA-Z]*/)[0].replace(" ", "");
year = timeStamp.getFullYear() == now.getFullYear() ? "" : " " + timeStamp.getFullYear();
return day + " " + month + year;
}
}
const currentTimeStamp = new Date().getTime();
console.log(timeSince(currentTimeStamp));
Gist https://gist.github.com/timuric/11386129
Fiddle http://jsfiddle.net/qE8Lu/1/
Hope it helps.
Well it's pretty easy if you aren't overly concerned with accuracy. What wrong with the trivial method?
function timeDifference(current, previous) {
var msPerMinute = 60 * 1000;
var msPerHour = msPerMinute * 60;
var msPerDay = msPerHour * 24;
var msPerMonth = msPerDay * 30;
var msPerYear = msPerDay * 365;
var elapsed = current - previous;
if (elapsed < msPerMinute) {
return Math.round(elapsed/1000) + ' seconds ago';
}
else if (elapsed < msPerHour) {
return Math.round(elapsed/msPerMinute) + ' minutes ago';
}
else if (elapsed < msPerDay ) {
return Math.round(elapsed/msPerHour ) + ' hours ago';
}
else if (elapsed < msPerMonth) {
return 'approximately ' + Math.round(elapsed/msPerDay) + ' days ago';
}
else if (elapsed < msPerYear) {
return 'approximately ' + Math.round(elapsed/msPerMonth) + ' months ago';
}
else {
return 'approximately ' + Math.round(elapsed/msPerYear ) + ' years ago';
}
}
Working example here.
You might want to tweak it to handle the singular values better (e.g. 1 day
instead of 1 days
) if that bothers you.