diff options
Diffstat (limited to 'date-fns/src/formatDuration/index.js')
-rw-r--r-- | date-fns/src/formatDuration/index.js | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/date-fns/src/formatDuration/index.js b/date-fns/src/formatDuration/index.js new file mode 100644 index 0000000..c4130a6 --- /dev/null +++ b/date-fns/src/formatDuration/index.js @@ -0,0 +1,100 @@ +import defaultLocale from '../locale/en-US/index' + +const defaultFormat = [ + 'years', + 'months', + 'weeks', + 'days', + 'hours', + 'minutes', + 'seconds', +] + +/** + * @name formatDuration + * @category Common Helpers + * @summary Formats a duration in human-readable format + * + * @description + * Return human-readable duration string i.e. "9 months 2 days" + * + * @param {Duration} duration - the duration to format + * @param {Object} [options] - an object with options. + + * @param {string[]} [options.format=['years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds']] - the array of units to format + * @param {boolean} [options.zero=false] - should be zeros be included in the output? + * @param {string} [options.delimiter=' '] - delimiter string + * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale} + * @returns {string} the formatted date string + * @throws {TypeError} 1 argument required + * + * @example + * // Format full duration + * formatDuration({ + * years: 2, + * months: 9, + * weeks: 1, + * days: 7, + * hours: 5, + * minutes: 9, + * seconds: 30 + * }) + * //=> '2 years 9 months 1 week 7 days 5 hours 9 minutes 30 seconds + * + * @example + * // Format partial duration + * formatDuration({ months: 9, days: 2 }) + * //=> '9 months 2 days' + * + * @example + * // Customize the format + * formatDuration( + * { + * years: 2, + * months: 9, + * weeks: 1, + * days: 7, + * hours: 5, + * minutes: 9, + * seconds: 30 + * }, + * { format: ['months', 'weeks'] } + * ) === '9 months 1 week' + * + * @example + * // Customize the zeros presence + * formatDuration({ years: 0, months: 9 }) + * //=> '9 months' + * formatDuration({ years: 0, months: 9 }, { zero: true }) + * //=> '0 years 9 months' + * + * @example + * // Customize the delimiter + * formatDuration({ years: 2, months: 9, weeks: 3 }, { delimiter: ', ' }) + * //=> '2 years, 9 months, 3 weeks' + */ +export default function formatDuration(duration, options) { + if (arguments.length < 1) { + throw new TypeError( + `1 argument required, but only ${arguments.length} present` + ) + } + + const format = options?.format || defaultFormat + const locale = options?.locale || defaultLocale + const zero = options?.zero || false + const delimiter = options?.delimiter || ' ' + + const result = format + .reduce((acc, unit) => { + const token = `x${unit.replace(/(^.)/, (m) => m.toUpperCase())}` + const addChunk = + typeof duration[unit] === 'number' && (zero || duration[unit]) + return addChunk + ? acc.concat(locale.formatDistance(token, duration[unit])) + : acc + }, []) + .join(delimiter) + + return result +} |