diff options
Diffstat (limited to 'date-fns/src/formatDuration')
-rw-r--r-- | date-fns/src/formatDuration/index.d.ts | 4 | ||||
-rw-r--r-- | date-fns/src/formatDuration/index.js | 100 | ||||
-rw-r--r-- | date-fns/src/formatDuration/index.js.flow | 60 | ||||
-rw-r--r-- | date-fns/src/formatDuration/test.js | 80 |
4 files changed, 244 insertions, 0 deletions
diff --git a/date-fns/src/formatDuration/index.d.ts b/date-fns/src/formatDuration/index.d.ts new file mode 100644 index 0000000..be96776 --- /dev/null +++ b/date-fns/src/formatDuration/index.d.ts @@ -0,0 +1,4 @@ +// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it. + +import { formatDuration } from 'date-fns' +export default formatDuration 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 +} diff --git a/date-fns/src/formatDuration/index.js.flow b/date-fns/src/formatDuration/index.js.flow new file mode 100644 index 0000000..022ea8e --- /dev/null +++ b/date-fns/src/formatDuration/index.js.flow @@ -0,0 +1,60 @@ +// @flow +// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it. + +export type Interval = { + start: Date | number, + end: Date | number, +} + +export type Locale = { + code?: string, + formatDistance?: (...args: Array<any>) => any, + formatRelative?: (...args: Array<any>) => any, + localize?: { + ordinalNumber: (...args: Array<any>) => any, + era: (...args: Array<any>) => any, + quarter: (...args: Array<any>) => any, + month: (...args: Array<any>) => any, + day: (...args: Array<any>) => any, + dayPeriod: (...args: Array<any>) => any, + }, + formatLong?: { + date: (...args: Array<any>) => any, + time: (...args: Array<any>) => any, + dateTime: (...args: Array<any>) => any, + }, + match?: { + ordinalNumber: (...args: Array<any>) => any, + era: (...args: Array<any>) => any, + quarter: (...args: Array<any>) => any, + month: (...args: Array<any>) => any, + day: (...args: Array<any>) => any, + dayPeriod: (...args: Array<any>) => any, + }, + options?: { + weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6, + firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7, + }, +} + +export type Duration = { + years?: number, + months?: number, + weeks?: number, + days?: number, + hours?: number, + minutes?: number, + seconds?: number, +} + +export type Day = 0 | 1 | 2 | 3 | 4 | 5 | 6 + +declare module.exports: ( + duration: Duration, + options?: { + format?: string[], + zero?: boolean, + delimiter?: string, + locale?: Locale, + } +) => string diff --git a/date-fns/src/formatDuration/test.js b/date-fns/src/formatDuration/test.js new file mode 100644 index 0000000..f9bb7af --- /dev/null +++ b/date-fns/src/formatDuration/test.js @@ -0,0 +1,80 @@ +// @flow +/* eslint-env mocha */ + +import assert from 'power-assert' +import formatDuration from '.' + +describe('formatDuration', () => { + it('formats full duration', () => { + assert( + 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' + ) + }) + + it('formats partial duration', () => { + assert(formatDuration({ months: 9, days: 2 }) === '9 months 2 days') + }) + + it('allows to customize the format', () => { + assert( + formatDuration( + { + years: 2, + months: 9, + weeks: 1, + days: 7, + hours: 5, + minutes: 9, + seconds: 30 + }, + { format: ['months', 'weeks'] } + ) === '9 months 1 week' + ) + }) + + it('does not include zeros by default', () => { + assert( + formatDuration({ + years: 0, + months: 0, + weeks: 1, + days: 0, + hours: 0, + minutes: 0, + seconds: 0 + }) === '1 week' + ) + }) + + it('allows to include zeros', () => { + assert( + formatDuration( + { + years: 0, + months: 0, + weeks: 1, + days: 0, + hours: 0, + minutes: 0, + seconds: 0 + }, + { zero: true } + ) === '0 years 0 months 1 week 0 days 0 hours 0 minutes 0 seconds' + ) + }) + + it('allows to customize the delimiter', () => { + assert( + formatDuration({ months: 9, days: 2 }, { delimiter: ', ' }) === + '9 months, 2 days' + ) + }) +}) |