Time durations appear everywhere - video players showing remaining time, fitness apps tracking workout lengths, or project management tools measuring task completion time. Formatting these durations consistently across different locales has traditionally required custom code or external libraries.
Intl.DurationFormat
Baseline 2025 newly available
Supported in Chrome: yes.
Supported in Edge: yes.
Supported in Firefox: yes.
Supported in Safari: yes.
Since March 2025 this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
The Intl.DurationFormat
object solves this problem elegantly. It’s part of ECMAScript’s core language specification - specifically the ECMAScript Internationalization API (ECMA-402). This makes it a native JavaScript feature rather than a web browser API, though browser implementation determines its availability.
At its core, Intl.DurationFormat
takes a duration object containing time units and formats it according to locale-specific rules. The basic usage is straightforward.
const duration = { hours: 2, minutes: 30 };const formatter = new Intl.DurationFormat('en-US', { style: 'long' });const result = formatter.format(duration);// Output: "2 hours and 30 minutes"
The duration object accepts multiple time units: years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, and nanoseconds. This flexibility allows you to represent any time span from nanoseconds to centuries.
The locale parameter determines how the duration appears based on language and regional conventions. English might use “and” before the final unit, while French employs “et” - these nuances happen automatically:
const duration = { hours: 1, minutes: 30 };
// English formattingnew Intl.DurationFormat('en-US', { style: 'long' }).format(duration);// "1 hour and 30 minutes"
// French formattingnew Intl.DurationFormat('fr-FR', { style: 'long' }).format(duration);// "1 heure et 30 minutes"
// Japanese formattingnew Intl.DurationFormat('ja-JP', { style: 'long' }).format(duration);// "1時間30分"
The output style can be customized through the options parameter. Three primary styles exist: ‘long’, ‘short’, and ‘narrow’. Each provides progressively more compact representations:
const duration = { hours: 2, minutes: 45, seconds: 30 };
// Long format - fully spelled outnew Intl.DurationFormat('en-US', { style: 'long' }).format(duration);// "2 hours, 45 minutes, and 30 seconds"
// Short format - abbreviated but clearnew Intl.DurationFormat('en-US', { style: 'short' }).format(duration);// "2 hr, 45 min, 30 sec"
// Narrow format - most compactnew Intl.DurationFormat('en-US', { style: 'narrow' }).format(duration);// "2h 45m 30s"
To wrap up this article, here’s a final example with all the possible duration units. It demonstrates the full range of time units and how Intl.DurationFormat
handles them.
// Full duration object using all possible time unitsconst fullDuration = { years: 2, months: 3, weeks: 1, days: 4, hours: 12, minutes: 30, seconds: 15, milliseconds: 300, microseconds: 750, nanoseconds: 500};
const formatter = style => new Intl.DurationFormat('en-US', { style });
// long format - fully spelled outconst formattedLongDuration = formatter('long').format(fullDuration);console.log(formattedLongDuration);// Output: "2 years, 3 months, 1 week, 4 days, 12 hours, 30 minutes, 15 seconds, 300 milliseconds, 750 microseconds, 500 nanoseconds"
// short format - abbreviated but clearconst formattedShortDuration = formatter('short').format(fullDuration);console.log(formattedShortDuration);// Output: "2 yrs, 3 mths, 1 wk, 4 days, 12 hr, 30 min, 15 sec, 300 ms, 750 μs, 500 ns"
// narrow format - most compactconst formattedNarrowDuration = formatter('narrow').format(fullDuration);console.log(formattedNarrowDuration);// Output: "2y 3m 1w 4d 12h 30m 15s 300ms 750μs 500ns"