Format relative time ("3 hours ago") with Intl
Turn a date into a localized relative string using Intl.RelativeTimeFormat, with no library.
- JavaScript
- GreenSnippets
- MIT
- Executed with Node.js 22
const UNITS = [
["year", 365 * 24 * 3600],
["month", 30 * 24 * 3600],
["week", 7 * 24 * 3600],
["day", 24 * 3600],
["hour", 3600],
["minute", 60],
];
function timeAgo(date, { locale = "en", now = Date.now() } = {}) {
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
const seconds = Math.round((new Date(date).getTime() - now) / 1000);
for (const [unit, size] of UNITS) {
if (Math.abs(seconds) >= size) return rtf.format(Math.trunc(seconds / size), unit);
}
return rtf.format(seconds, "second");
}Example / expected output
timeAgo(Date.now() - 3 * 3600 * 1000) // "3 hours ago"How it works
Intl.RelativeTimeFormat handles pluralization and localization. The helper picks the largest unit that fits. For server-rendered pages pass a fixed now so server and client output match and you avoid hydration mismatches.
Related snippets
- SQL
Fill in missing dates with generate_series
Produce a row for every day in a range and left join your data so days with no activity show zero.
- JavaScript Tested
Truncate a string with an ellipsis
Shorten text to a maximum length without cutting in the middle of a word or a Unicode character.
- PHP Tested
Truncate multibyte strings safely in PHP
Shorten UTF-8 text with mb_ functions so accents and emoji are never cut in half.
- Python Tested
Slugify a string
Turn text into a lowercase, hyphenated, ASCII-only slug using only the standard library.

