Skip to content

Instantly share code, notes, and snippets.

@hoseinhamzei
Created June 8, 2025 15:37
Show Gist options
  • Save hoseinhamzei/0c10dc80939440c38f9b220cc676465c to your computer and use it in GitHub Desktop.
Save hoseinhamzei/0c10dc80939440c38f9b220cc676465c to your computer and use it in GitHub Desktop.
Native Relative Time Formatting In Typescript/Javascript
export function getRelativeTime(
date: Date | string | number,
locale: string = navigator.language
): string {
// normalize to a Date, and bail out if it’s invalid
const target =
typeof date === 'string' || typeof date === 'number'
? new Date(date)
: date;
if (isNaN(target.getTime())) {
console.warn(`getRelativeTime: invalid date input ${date}`);
return '';
}
// compute difference in seconds
const now = Date.now();
const diffSec = Math.round((target.getTime() - now) / 1000);
// table of thresholds, the corresponding unit, and how many seconds each unit represents
const intervals: Array<{
limit: number;
unit: Intl.RelativeTimeFormatUnit;
secsPerUnit: number;
}> = [
{ limit: 60, unit: 'second', secsPerUnit: 1 },
{ limit: 3600, unit: 'minute', secsPerUnit: 60 },
{ limit: 86400, unit: 'hour', secsPerUnit: 3600 },
{ limit: 604800, unit: 'day', secsPerUnit: 86400 },
{ limit: 2592000, unit: 'week', secsPerUnit: 604800 },
{ limit: 31536000, unit: 'month', secsPerUnit: 2592000 },
{ limit: Infinity, unit: 'year', secsPerUnit: 31536000 },
];
// find the first interval where |diffSec| < limit
const { unit, secsPerUnit } = intervals.find(
(i) => Math.abs(diffSec) < i.limit
)!;
// compute how many of those units
const value = Math.round(diffSec / secsPerUnit);
// format via Intl.RelativeTimeFormat
const rtf = new Intl.RelativeTimeFormat(locale, {
numeric: 'auto',
style: 'long',
});
return rtf.format(value, unit);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment