Format a Countdown as Days, Hours, Minutes in JavaScript
To format a countdown, balance the remaining Temporal.Duration with round, then render it with Intl.DurationFormat for localized unit words. Part of Intl.DurationFormat for Human-Readable Durations.
Why this scenario is tricky
A countdown display couples two concerns: computing the balanced remaining duration (days, hours, minutes) and rendering it in the user's language. Manual string building handles neither pluralization nor locale word order; Intl.DurationFormat does both, and Temporal.Duration.round supplies the balanced record it formats.
Minimal working solution
import { Temporal } from '@js-temporal/polyfill';
const rem = target.since(Temporal.Now.instant(), { largestUnit: 'day' })
.round({ largestUnit: 'day', smallestUnit: 'minute' });
new Intl.DurationFormat('en', { style: 'short' }).format(rem); // '2 days, 3 hr, 5 min'
Full production version
import { Temporal } from '@js-temporal/polyfill';
function countdownText(target: Temporal.Instant, locale = 'en'): string {
const rem = target.since(Temporal.Now.instant(), { largestUnit: 'day', smallestUnit: 'minute' });
if (Temporal.Duration.compare(rem, {}) <= 0) return 'now';
return new Intl.DurationFormat(locale, { style: 'short' }).format(rem);
}
Verification snippet
Common pitfalls
Frequently Asked Questions
How do I format a countdown as days, hours, and minutes?
Compute the remaining time as a Temporal.Duration with target.since(now), balance it with round({ largestUnit: 'day', smallestUnit: 'minute' }), and pass it to Intl.DurationFormat. That yields a localized string like '2 days, 3 hr, 5 min' with correct plurals.
Why use Intl.DurationFormat instead of building the string myself?
Manual strings hard-code English unit words and miss pluralization and locale ordering. Intl.DurationFormat renders the balanced duration record in the user's language, and pairing it with Temporal.Duration.round keeps the numbers balanced.