Format a timestamp as relative time
Every feed, comment thread and notification list shows relative times. Passing now in explicitly rather than reading the clock inside is what makes the function testable — and it is why this version is deterministic.
Implement formatRelativeTime(timestamp, now), both epoch milliseconds. Let seconds = Math.round((now - timestamp) / 1000) — positive means the past — and abs = Math.abs(seconds).
If abs is under 60, return exactly "just now". Otherwise pick the first unit whose limit abs falls under, and take Math.floor(abs / size) as the value: minute (size 60, limit 3600), hour (3600, 86400), day (86400, 604800), week (604800, 2592000), month (2592000, 31536000), and otherwise year (size 31536000).
Build the label as the value, a space, the unit name, plus an s unless the value is exactly 1. Return "<label> ago" when seconds is positive and "in <label>" when it is negative.
Arguments
timestampnumber- The event's epoch milliseconds.
nownumber- The reference time in epoch milliseconds. Passed in rather than read from the clock so the function stays deterministic.
Returns
string — A human relative time: "just now", "<n> <unit> ago" for past times, or "in <n> <unit>" for future times.
Examples
formatRelativeTime(0, 5 * 60 * 1000);
// => "5 minutes ago"The unit is pluralised when the value is not exactly 1.
formatRelativeTime(0, 3600 * 1000);
// => "1 hour ago"Exactly one of a unit drops the trailing s.
formatRelativeTime(2 * 86400 * 1000, 0);
// => "in 2 days"Future times — when now < timestamp — use an in ... prefix instead of a suffix.
What it has to do
- Return
"just now"when the difference is under 60 seconds in either direction. - Use the largest unit that fits, flooring the value, across minute, hour, day, week, month and year.
- Pluralise the unit with a trailing
sunless the value is exactly 1. - Suffix past times with
" ago"and prefix future times with"in ". - Take
nowas an argument rather than reading the clock.
Notes
- Passing
nowas an argument is the single trick that makes this function testable: a caller can anchor time at a known value and assert the label without flaky clocks. - This uses fixed-size months and years — 30 and 365 days. Real
Intl.RelativeTimeFormatoutput chooses units with calendar awareness, so switch to that when you need localisation and leap-aware boundaries.
Stuck? The javascript course covers everything this challenge needs.
- 1.returns just now for a small difference
- 2.pluralises minutes
- 3.uses the singular form for exactly one hour
- 4.switches to days
- 5.phrases future timestamps with a prefix
These assertions run in your browser the moment you hit Run. Pass all of them to claim the XP.
Discussion
Sign in to postNo comments yet. Be the first to say something.