Convert milliseconds to a human readable string:
1337000000→15d 11h 23m 20s
See parse-duration-ms for the inverse.
npm install pretty-ms
import prettyMilliseconds from 'pretty-ms';
prettyMilliseconds(1337000000);
//=> '15d 11h 23m 20s'
prettyMilliseconds(1337000000n);
//=> '15d 11h 23m 20s'
prettyMilliseconds(1337);
//=> '1.3s'
prettyMilliseconds(133);
//=> '133ms'
// `compact` option
prettyMilliseconds(1337, {compact: true});
//=> '1s'
// `verbose` option
prettyMilliseconds(1335669000, {verbose: true});
//=> '15 days 11 hours 1 minute 9 seconds'
// `colonNotation` option
prettyMilliseconds(95500, {colonNotation: true});
//=> '1:35.5'
// `formatSubMilliseconds` option
prettyMilliseconds(100.400080, {formatSubMilliseconds: true})
//=> '100ms 400µs 80ns'
// `subSecondsAsDecimals` option
prettyMilliseconds(900, {subSecondsAsDecimals: true});
//=> '0.9s'
// Can be useful for time durations
prettyMilliseconds(new Date(2014, 0, 1, 10, 40) - new Date(2014, 0, 1, 10, 5))
//=> '35m'
Type: number | bigint
Milliseconds to humanize.
An integer (number or bigint) is exact at any size.
A fractional number is first rounded to 15 significant digits, the precision of a number, which removes float noise:
0.57 * 100_000 (56999.99999999999) is 57s.999.9999999999999 (16 digits) is 1s, but 999.99999999999 (14 digits) is 999ms.From 1e14 milliseconds (about 3,170 years) up, no digits are left for the fraction, so the duration is rounded to whole milliseconds, and from 1e15 (about 31,700 years) up, to the nearest 10 milliseconds.
Type: object
Type: number
Default: 1
Number of digits to appear after the seconds decimal point.
Digits are floored, not rounded, so the seconds never round up into the next step: 1999ms is 1.9s, and at 0 digits it is 1s, never 2s. The flooring applies to the duration after it is read (see milliseconds for how a fractional number is read).
Type: number
Default: 0
Number of digits to appear after the milliseconds decimal point.
The milliseconds are rounded, not floored, but they never round up to 1000ms, and a nonzero duration under a second never rounds down to 0ms: 999.6ms is 999ms, and 0.2ms is 1ms. This does not apply with formatSubMilliseconds, which floors instead.
Useful in combination with process.hrtime().
Type: boolean
Default: false
Keep milliseconds on whole seconds: 13s → 13.0s.
Useful when you are showing a number of seconds spent on an operation and don't want the width of the output to change when hitting a whole number.
Type: boolean
Default: false
Only show the first unit: 1h 10m → 1h.
Also ensures that millisecondsDecimalDigits and secondsDecimalDigits are both set to 0.
Type: number
Default: Infinity
Number of units to show. Setting compact to true overrides this option. It is ignored with colonNotation.
Type: boolean
Default: false
Use full-length units: 5h 1m 45s → 5 hours 1 minute 45 seconds
Type: boolean
Default: false
Show milliseconds separately. This means they won't be included in the decimal part of the seconds.
Type: boolean
Default: false
Show microseconds and nanoseconds.
The values are floored to whole nanoseconds, so a duration under 1 nanosecond is 0ms.
Type: boolean
Default: false
Display time using colon notation: 5h 1m 45s → 5:01:45. Always shows time in at least minutes: 1s → 0:01, or in at least hours with hideSeconds: 1m → 0:01.
Useful when you want to display time without the time units, similar to a digital watch.
Setting colonNotation to true overrides the following options to false:
compactformatSubMillisecondsseparateMillisecondsverboseDays after a year are padded to 3 digits to keep the width: 1:005:00:00:00.
It also ignores unitCount, as dropping a field would change what the remaining fields mean: 1:01:01 would become 1:01, which reads as 1 minute.
Type: boolean
Default: false
Hides the year and shows the hidden year additionally as days (365 per year): 1y 3d 5h 1m 45s → 368d 5h 1m 45s.
Type: boolean
Default: false
Hides the year and days and shows the hidden values additionally as hours: 1y 3d 5h 1m 45s → 8837h 1m 45s.
Type: boolean
Default: false
Hides the seconds: 1y 3d 5h 1m 45s → 1y 3d 5h 1m.
A duration under a minute has no coarser unit, so it keeps its seconds rather than showing nothing. With colonNotation, the hours are always shown, so the fields read as h:mm: 60000 → 0:01, and 45000 → 0:00:45.
Type: boolean
Default: false
Show sub-second values as decimal seconds: 900ms → 0.9s.
Useful for progress indicators where you want consistent unit format to prevent flickering.
Also floored, so 999ms is 0.9s.
A duration too small for the seconds field to show, like 50ms at the default secondsDecimalDigits of 1, stays in milliseconds rather than showing as zero. With compact, the seconds have no decimals, so a duration under a second stays in milliseconds.
This package formats time durations, not calendar dates. Months (28-31 days) have variable lengths, making duration calculations ambiguous. Years are shown as a fixed 365 days, so they do not account for leap years. Use the hideYear option to show days as the largest unit, since days are always exactly 24 hours. For calendar-based formatting, use Temporal API or a date library like date-fns.
prettyMilliseconds(3670); //=> '3.6s'
prettyMilliseconds(5230); //=> '5.2s'
prettyMilliseconds(5230 - 3670); //=> '1.5s' // Not '1.6s'
This is inherent to displaying rounded numbers, the same reason rounded percentages don't always add up to 100%. Values are rounded independently, and rounding does not distribute over subtraction. prettyMilliseconds(5230 - 3670) correctly represents the true difference; it just won't always match subtracting the two rounded strings by eye.