summaryrefslogtreecommitdiff
path: root/date-fns/src/formatDuration
diff options
context:
space:
mode:
Diffstat (limited to 'date-fns/src/formatDuration')
-rw-r--r--date-fns/src/formatDuration/index.d.ts4
-rw-r--r--date-fns/src/formatDuration/index.js100
-rw-r--r--date-fns/src/formatDuration/index.js.flow60
-rw-r--r--date-fns/src/formatDuration/test.js80
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'
+ )
+ })
+})