Skip to content

Instantly share code, notes, and snippets.

@victornpb
Last active April 30, 2021 18:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save victornpb/d06dd7b5b2f408039d25b351794a3608 to your computer and use it in GitHub Desktop.
Save victornpb/d06dd7b5b2f408039d25b351794a3608 to your computer and use it in GitHub Desktop.
/**
* Human readable elapsed or remaining time (example: 3 minutes ago)
* @param {Date|Number|String} date A Date object, timestamp or string parsable with Date.parse()
* @return {string} Human readable elapsed or remaining time
* @author github.com/victornpb
*/
function fromNow(date) {
const SECOND = 1000;
const MINUTE = 60 * SECOND;
const HOUR = 60 * MINUTE;
const DAY = 24 * HOUR;
const WEEK = 7 * DAY;
const MONTH = 30 * DAY;
const YEAR = 365 * DAY;
const intervals = [
{ ge: 2 * YEAR, divisor: YEAR, elapsed: '# years ago', remaining: 'in # years' },
{ ge: YEAR, divisor: YEAR, elapsed: 'last year', remaining: 'in a year' },
{ ge: 2 * MONTH, divisor: MONTH, elapsed: '# months ago', remaining: 'in # months' },
{ ge: MONTH, divisor: MONTH, elapsed: 'last month', remaining: 'in a month' },
{ ge: 2 * WEEK, divisor: WEEK, elapsed: '# weeks ago', remaining: 'in # weeks' },
{ ge: WEEK, divisor: WEEK, elapsed: 'last week', remaining: 'in a week' },
{ ge: 2 * DAY, divisor: DAY, elapsed: '# days ago', remaining: 'in # days' },
{ ge: DAY, divisor: DAY, elapsed: 'yesterday', remaining: 'tomorrow', },
{ ge: 2 * HOUR, divisor: HOUR, elapsed: '# hours ago', remaining: 'in # hours' },
{ ge: HOUR, divisor: HOUR, elapsed: 'an hour ago', remaining: 'in an hour' },
{ ge: 2 * MINUTE, divisor: MINUTE, elapsed: '# minutes ago', remaining: 'in # minutes' },
{ ge: MINUTE, divisor: MINUTE, elapsed: 'a minute ago', remaining: 'in a minute' },
{ ge: 30 * SECOND, divisor: SECOND, elapsed: '# seconds ago', remaining: 'in # seconds' },
{ ge: 0, divisor: 1, elapsed: 'just now', remaining: 'just now' },
];
const diff = Date.now() - (typeof date === 'object' ? date : new Date(date)).getTime();
const diffAbs = Math.abs(diff);
for (const interval of intervals) {
if (diffAbs >= interval.ge) {
const x = Math.round(Math.abs(diff) / interval.divisor);
const isFuture = diff < 0;
return String(isFuture ? interval.remaining : interval.elapsed).replace('#', x);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment