UNPKG

2.58 kBJavaScriptView Raw
1import { defaultLocale } from "./_lib/defaultLocale.mjs";
2import { getDefaultOptions } from "./_lib/defaultOptions.mjs";
3
4/**
5 * The {@link formatDuration} function options.
6 */
7
8const defaultFormat = [
9 "years",
10 "months",
11 "weeks",
12 "days",
13 "hours",
14 "minutes",
15 "seconds",
16];
17
18/**
19 * @name formatDuration
20 * @category Common Helpers
21 * @summary Formats a duration in human-readable format
22 *
23 * @description
24 * Return human-readable duration string i.e. "9 months 2 days"
25 *
26 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
27 *
28 * @param duration - The duration to format
29 * @param options - An object with options.
30 *
31 * @returns The formatted date string
32 *
33 * @example
34 * // Format full duration
35 * formatDuration({
36 * years: 2,
37 * months: 9,
38 * weeks: 1,
39 * days: 7,
40 * hours: 5,
41 * minutes: 9,
42 * seconds: 30
43 * })
44 * //=> '2 years 9 months 1 week 7 days 5 hours 9 minutes 30 seconds'
45 *
46 * @example
47 * // Format partial duration
48 * formatDuration({ months: 9, days: 2 })
49 * //=> '9 months 2 days'
50 *
51 * @example
52 * // Customize the format
53 * formatDuration(
54 * {
55 * years: 2,
56 * months: 9,
57 * weeks: 1,
58 * days: 7,
59 * hours: 5,
60 * minutes: 9,
61 * seconds: 30
62 * },
63 * { format: ['months', 'weeks'] }
64 * ) === '9 months 1 week'
65 *
66 * @example
67 * // Customize the zeros presence
68 * formatDuration({ years: 0, months: 9 })
69 * //=> '9 months'
70 * formatDuration({ years: 0, months: 9 }, { zero: true })
71 * //=> '0 years 9 months'
72 *
73 * @example
74 * // Customize the delimiter
75 * formatDuration({ years: 2, months: 9, weeks: 3 }, { delimiter: ', ' })
76 * //=> '2 years, 9 months, 3 weeks'
77 */
78export function formatDuration(duration, options) {
79 const defaultOptions = getDefaultOptions();
80 const locale = options?.locale ?? defaultOptions.locale ?? defaultLocale;
81 const format = options?.format ?? defaultFormat;
82 const zero = options?.zero ?? false;
83 const delimiter = options?.delimiter ?? " ";
84
85 if (!locale.formatDistance) {
86 return "";
87 }
88
89 const result = format
90 .reduce((acc, unit) => {
91 const token = `x${unit.replace(/(^.)/, (m) => m.toUpperCase())}`;
92 const value = duration[unit];
93 if (value !== undefined && (zero || duration[unit])) {
94 return acc.concat(locale.formatDistance(token, value));
95 }
96 return acc;
97 }, [])
98 .join(delimiter);
99
100 return result;
101}
102
103// Fallback for modularized imports:
104export default formatDuration;