Relative Time Formatting (ago, in, just now)
Implement relative time displays like '5 minutes ago' and 'in 3 days'. Learn Intl.RelativeTimeFormat, library solutions, and best practices for user-friendly timestamps.
Detailed Explanation
Relative Time Formatting
Relative time displays like "5 minutes ago", "in 2 hours", or "yesterday" are more intuitive than absolute timestamps for recent events. Every social media platform, chat app, and notification system uses this pattern.
Intl.RelativeTimeFormat (Native JavaScript)
Modern browsers and Node.js support the Intl.RelativeTimeFormat API:
const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
rtf.format(-1, "day"); // "yesterday"
rtf.format(-5, "minute"); // "5 minutes ago"
rtf.format(3, "hour"); // "in 3 hours"
rtf.format(0, "day"); // "today"
// With numeric: "always"
const rtf2 = new Intl.RelativeTimeFormat("en", { numeric: "always" });
rtf2.format(-1, "day"); // "1 day ago"
Localization
// Japanese
new Intl.RelativeTimeFormat("ja").format(-5, "minute");
// "5 分前"
// German
new Intl.RelativeTimeFormat("de").format(-1, "day");
// "vor 1 Tag"
// French
new Intl.RelativeTimeFormat("fr").format(2, "hour");
// "dans 2 heures"
Implementation Logic
The typical algorithm for choosing the appropriate unit:
function relativeTime(date) {
const diff = Date.now() - date.getTime();
const abs = Math.abs(diff);
const sign = diff > 0 ? -1 : 1;
if (abs < 60_000) return "just now";
if (abs < 3_600_000) return rtf.format(sign * Math.floor(abs / 60_000), "minute");
if (abs < 86_400_000) return rtf.format(sign * Math.floor(abs / 3_600_000), "hour");
if (abs < 2_592_000_000) return rtf.format(sign * Math.floor(abs / 86_400_000), "day");
if (abs < 31_536_000_000) return rtf.format(sign * Math.floor(abs / 2_592_000_000), "month");
return rtf.format(sign * Math.floor(abs / 31_536_000_000), "year");
}
Library Solutions
| Library | Function | Example |
|---|---|---|
| date-fns | formatDistanceToNow() |
"5 minutes ago" |
| Day.js | dayjs().fromNow() |
"5 minutes ago" |
| moment.js | moment().fromNow() |
"5 minutes ago" |
| Luxon | DateTime.toRelative() |
"5 minutes ago" |
Best Practices
- Show absolute time on hover/long-press — always let users see the exact timestamp
- Stop updating after a threshold — switch to absolute dates after 7 days or 30 days
- Use "just now" for < 1 minute — avoid "0 seconds ago"
- Consider real-time updates — use
setIntervalorrequestAnimationFramefor live feeds - Respect locale — use Intl API or library i18n for proper pluralization rules
Use Case
Relative time formatting is essential for social media feeds (Twitter, Reddit), chat applications (Slack, Discord), notification systems, comment sections, email clients (inbox timestamps), version control history (commit dates), and any UI where recent activity is displayed.