From a26ea0386c915aa575164e53977dd0f73d9394e6 Mon Sep 17 00:00:00 2001 From: Ted Driggs Date: Wed, 8 Nov 2017 09:56:31 -0800 Subject: [PATCH] [feature] Accept custom relative thresholds in duration.humanize Fixes #4295 --- moment.d.ts | 15 ++++++++++++++- src/lib/duration/humanize.js | 28 +++++++++++++++++++++++++--- src/test/moment/duration.js | 23 +++++++++++++++++++++++ 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/moment.d.ts b/moment.d.ts index 9198eda6bd..78a76b2adc 100644 --- a/moment.d.ts +++ b/moment.d.ts @@ -154,10 +154,23 @@ declare namespace moment { milliseconds: number; } + interface HumanizeOptions { + withSuffix?: boolean; + thresholds?: { + ss?: number; + s?: number; + m?: number; + h?: number; + d?: number; + w?: number | void; + M?: number; + }; + } + interface Duration { clone(): Duration; - humanize(withSuffix?: boolean): string; + humanize(withSuffixOrOptions?: boolean | HumanizeOptions): string; abs(): Duration; diff --git a/src/lib/duration/humanize.js b/src/lib/duration/humanize.js index 947bb91fba..e0e3d8a6c2 100644 --- a/src/lib/duration/humanize.js +++ b/src/lib/duration/humanize.js @@ -16,7 +16,7 @@ function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); } -function relativeTime (posNegDuration, withoutSuffix, locale) { +function relativeTime (posNegDuration, withoutSuffix, thresholds, locale) { var duration = createDuration(posNegDuration).abs(); var seconds = round(duration.as('s')); var minutes = round(duration.as('m')); @@ -78,13 +78,35 @@ export function getSetRelativeTimeThreshold (threshold, limit) { return true; } -export function humanize (withSuffix) { +export function humanize (withSuffixOrOptions) { if (!this.isValid()) { return this.localeData().invalidDate(); } + var withSuffix = false; + var th = thresholds; + + if (typeof withSuffixOrOptions === 'boolean') { + withSuffix = withSuffixOrOptions; + } + else if (typeof withSuffixOrOptions === 'object') { + var ws = withSuffixOrOptions.withSuffix; + if (typeof ws === 'boolean') { + withSuffix = ws; + } + + var t = withSuffixOrOptions.thresholds; + if (typeof t === 'object') { + // Fill in missing keys with the current values + th = Object.assign({}, thresholds, t); + if (typeof t.s === 'number') { + th.ss = t.s - 1; + } + } + } + var locale = this.localeData(); - var output = relativeTime(this, !withSuffix, locale); + var output = relativeTime(this, !withSuffix, th, locale); if (withSuffix) { output = locale.pastFuture(+this, output); diff --git a/src/test/moment/duration.js b/src/test/moment/duration.js index 135a9a3c2e..e0f5212ea7 100644 --- a/src/test/moment/duration.js +++ b/src/test/moment/duration.js @@ -464,6 +464,29 @@ test('humanize duration with suffix', function (assert) { assert.equal(moment.duration({seconds: 44}).humanize(true), 'in a few seconds', '44 seconds = a few seconds'); assert.equal(moment.duration({seconds: -44}).humanize(true), 'a few seconds ago', '44 seconds = a few seconds'); assert.equal(moment.duration({seconds: +44}).humanize(true), 'in a few seconds', '44 seconds = a few seconds'); + assert.equal(moment.duration({seconds: 44}).humanize({withSuffix: true}), 'in a few seconds', '44 seconds = a few seconds'); + assert.equal(moment.duration({seconds: -44}).humanize({withSuffix: true}), 'a few seconds ago', '44 seconds = a few seconds'); + assert.equal(moment.duration({seconds: +44}).humanize({withSuffix: true}), 'in a few seconds', '44 seconds = a few seconds'); +}); + +test('humanize duration with options', function (assert) { + var thresholds = {s: 9}; + moment.locale('en'); + assert.equal( + moment.duration({seconds: -10}).humanize({thresholds: thresholds}), + 'a minute', + '10 seconds = a minute (with thresholds)' + ); + assert.equal( + moment.duration({seconds: 10}).humanize({thresholds: thresholds, withSuffix: true}), + 'in a minute', + '10 seconds = a minute (with thresholds and suffix)' + ); + assert.equal( + moment.duration({weeks: 3}).humanize({thresholds: {d: 7, w: 4}, withSuffix: true}), + 'in 3 weeks', + 'in 3 weeks = in 3 weeks (with thresholds and suffix)' + ); }); test('bubble value up', function (assert) {