diff --git a/moment.d.ts b/moment.d.ts index 24667a3f5a..6a2594bcd0 100644 --- a/moment.d.ts +++ b/moment.d.ts @@ -153,10 +153,23 @@ declare namespace moment { milliseconds: number; } + interface HumanizeOptions { + withSuffix?: boolean; + thresholds?: { + ss?: number; + s?: number; + m?: number; + h?: number; + d?: number; + M?: number; + y?: 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 454b01ae51..b0296a7b60 100644 --- a/src/lib/duration/humanize.js +++ b/src/lib/duration/humanize.js @@ -15,7 +15,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')); @@ -69,13 +69,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 9ca6c216ec..ba9ce07997 100644 --- a/src/test/moment/duration.js +++ b/src/test/moment/duration.js @@ -464,6 +464,24 @@ 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)' + ); }); test('bubble value up', function (assert) {