diff --git a/src/duration.ts b/src/duration.ts index 58492b2..69ddda1 100644 --- a/src/duration.ts +++ b/src/duration.ts @@ -128,94 +128,74 @@ export function elapsedTime(date: Date, precision: Unit = 'second', now = Date.n ) } +const durationRoundingThresholds = [ + Infinity, // Year + 11, // Month + 28, // Day + 21, // Hour + 55, // Minute + 55, // Second + 900, // Millisecond +] + interface RoundingOpts { relativeTo: Date | number } export function roundToSingleUnit(duration: Duration, {relativeTo = Date.now()}: Partial = {}): Duration { - relativeTo = new Date(relativeTo) if (duration.blank) return duration - const sign = duration.sign - let years = Math.abs(duration.years) - let months = Math.abs(duration.months) - let weeks = Math.abs(duration.weeks) - let days = Math.abs(duration.days) - let hours = Math.abs(duration.hours) - let minutes = Math.abs(duration.minutes) - let seconds = Math.abs(duration.seconds) - let milliseconds = Math.abs(duration.milliseconds) - - if (milliseconds >= 900) seconds += Math.round(milliseconds / 1000) - if (seconds || minutes || hours || days || weeks || months || years) { - milliseconds = 0 - } - - if (seconds >= 55) minutes += Math.round(seconds / 60) - if (minutes || hours || days || weeks || months || years) seconds = 0 - - if (minutes >= 55) hours += Math.round(minutes / 60) - if (hours || days || weeks || months || years) minutes = 0 - - if (days && hours >= 12) days += Math.round(hours / 24) - if (!days && hours >= 21) days += Math.round(hours / 24) - if (days || weeks || months || years) hours = 0 - - // Resolve calendar dates - const currentYear = relativeTo.getFullYear() - const currentMonth = relativeTo.getMonth() - const currentDate = relativeTo.getDate() - if (days >= 27 || years + months + days) { - const newMonthDate = new Date(relativeTo) - newMonthDate.setDate(1) - newMonthDate.setMonth(currentMonth + months * sign + 1) - newMonthDate.setDate(0) - const monthDateCorrection = Math.max(0, currentDate - newMonthDate.getDate()) - - const newDate = new Date(relativeTo) - newDate.setFullYear(currentYear + years * sign) - newDate.setDate(currentDate - monthDateCorrection) - newDate.setMonth(currentMonth + months * sign) - newDate.setDate(currentDate - monthDateCorrection + days * sign) - const yearDiff = newDate.getFullYear() - relativeTo.getFullYear() - const monthDiff = newDate.getMonth() - relativeTo.getMonth() - const daysDiff = Math.abs(Math.round((Number(newDate) - Number(relativeTo)) / 86400000)) + monthDateCorrection - const monthsDiff = Math.abs(yearDiff * 12 + monthDiff) - if (daysDiff < 27) { - if (days >= 6) { - weeks += Math.round(days / 7) - days = 0 + const referenceDate = new Date(relativeTo) + const specifiedDate = applyDuration(referenceDate, duration) + const [sign, subtrahend, minuend] = + specifiedDate < referenceDate ? [-1, referenceDate, specifiedDate] : [1, specifiedDate, referenceDate] + const subtrahendWithoutTime = new Date(subtrahend) + subtrahendWithoutTime.setHours(0) + subtrahendWithoutTime.setMinutes(0) + subtrahendWithoutTime.setSeconds(0) + subtrahendWithoutTime.setMilliseconds(0) + const minuendWithoutTime = new Date(minuend) + minuendWithoutTime.setHours(0) + minuendWithoutTime.setMinutes(0) + minuendWithoutTime.setSeconds(0) + minuendWithoutTime.setMilliseconds(0) + if ( + subtrahendWithoutTime.getTime() === minuendWithoutTime.getTime() || + subtrahend.getTime() - minuend.getTime() < 1000 * 60 * 60 * 12 + ) { + const difference = Math.round((subtrahend.getTime() - minuend.getTime()) / 1000) + let hours = Math.floor(difference / 3600) + let minutes = Math.floor((difference % 3600) / 60) + const seconds = Math.floor(difference % 60) + if (hours === 0) { + if (seconds >= durationRoundingThresholds[5]) minutes += 1 + if (minutes >= durationRoundingThresholds[4]) { + return new Duration(0, 0, 0, 0, 1 * sign) // 1 hour. + } + if (minutes === 0) { + return new Duration(0, 0, 0, 0, 0, 0, seconds * sign) } else { - days = daysDiff + return new Duration(0, 0, 0, 0, 0, minutes * sign) } - months = years = 0 - } else if (monthsDiff <= 11) { - months = monthsDiff - years = 0 } else { - months = 0 - years = yearDiff * sign + if (hours < 23 && minutes >= durationRoundingThresholds[4]) hours += 1 + return new Duration(0, 0, 0, 0, hours * sign) } - if (months || years) days = 0 } - if (years) months = 0 - - if (weeks >= 4) months += Math.round(weeks / 4) - if (months || years) weeks = 0 - if (days && weeks && !months && !years) { - weeks += Math.round(days / 7) - days = 0 + const days = Math.round((subtrahendWithoutTime.getTime() - minuendWithoutTime.getTime()) / (1000 * 60 * 60 * 24)) + const months = + subtrahend.getFullYear() * 12 + subtrahend.getMonth() - (minuend.getFullYear() * 12 + minuend.getMonth()) + if (months === 0 || days <= 26) { + if (days >= 6) { + return new Duration(0, 0, Math.floor((days + 1) / 7) * sign) // Weeks. + } else { + return new Duration(0, 0, 0, days * sign) + } + } + if (months < 12) { + return new Duration(0, months * sign) + } else { + return new Duration((subtrahend.getFullYear() - minuend.getFullYear()) * sign) } - - return new Duration( - years * sign, - months * sign, - weeks * sign, - days * sign, - hours * sign, - minutes * sign, - seconds * sign, - milliseconds * sign, - ) } export function getRelativeTimeUnit( diff --git a/src/relative-time-element.ts b/src/relative-time-element.ts index 068183d..096dc19 100644 --- a/src/relative-time-element.ts +++ b/src/relative-time-element.ts @@ -1,4 +1,4 @@ -import {Duration, elapsedTime, getRelativeTimeUnit, isDuration, roundToSingleUnit, Unit, unitNames} from './duration.js' +import {Duration, Unit, elapsedTime, getRelativeTimeUnit, isDuration, roundToSingleUnit, unitNames} from './duration.js' const HTMLElement = globalThis.HTMLElement || (null as unknown as typeof window['HTMLElement']) export type DeprecatedFormat = 'auto' | 'micro' | 'elapsed' @@ -157,6 +157,7 @@ export class RelativeTimeElement extends HTMLElement implements Intl.DateTimeFor const tense = this.tense let empty = emptyDuration if (format === 'micro') { + // TODO: Switch to `roundBalancedToSingleUnit` after integrating the new `elapsedTime` implementation. duration = roundToSingleUnit(duration) empty = microEmptyDuration if ((this.tense === 'past' && duration.sign !== -1) || (this.tense === 'future' && duration.sign !== 1)) { diff --git a/test/duration.ts b/test/duration.ts index ecb9e68..ef192df 100644 --- a/test/duration.ts +++ b/test/duration.ts @@ -241,10 +241,13 @@ suite('duration', function () { ['PT1H29M', 'PT1H'], ['PT1H31M', 'PT1H'], ['PT1H55M', 'PT2H'], - ['PT20H', 'PT20H'], - ['PT21H', 'P1D'], - ['P1DT20H', 'P2D'], - ['P1DT18H', 'P2D'], + ['PT10H', 'PT10H', {relativeTo: new Date('2023-07-01T20:00:00')}], + ['-PT10H', '-PT10H', {relativeTo: new Date('2023-07-01T00:00:00')}], + ['PT20H', 'PT20H', {relativeTo: new Date('2023-07-01T00:00:00')}], + ['-PT20H', '-PT20H', {relativeTo: new Date('2023-07-01T20:00:00')}], + ['PT20H', 'P1D', {relativeTo: new Date('2023-07-01T12:00:00')}], + ['-PT20H', '-P1D', {relativeTo: new Date('2023-07-01T12:00:00')}], + ['P1DT20H', 'P2D', {relativeTo: new Date('2023-07-01T12:00:00')}], ['P4D', 'P4D', {relativeTo: new Date('2023-07-01T00:00:00')}], ['-P4D', '-P4D', {relativeTo: new Date('2023-07-01T00:00:00')}], ['P6D', 'P1W', {relativeTo: new Date('2023-07-01T00:00:00')}], @@ -253,18 +256,18 @@ suite('duration', function () { ['-P2W', '-P2W', {relativeTo: new Date('2023-07-01T00:00:00')}], ['P3W3D', 'P3W', {relativeTo: new Date('2023-07-01T00:00:00')}], ['-P3W3D', '-P3W', {relativeTo: new Date('2023-07-01T00:00:00')}], - ['P3W6D', 'P1M', {relativeTo: new Date('2023-07-01T00:00:00')}], + ['P3W6D', 'P4W', {relativeTo: new Date('2023-07-01T00:00:00')}], + ['-P3W6D', '-P4W', {relativeTo: new Date('2023-07-30T00:00:00')}], + ['P3W6D', 'P1M', {relativeTo: new Date('2023-07-30T00:00:00')}], ['-P3W6D', '-P1M', {relativeTo: new Date('2023-07-01T00:00:00')}], ['P21D', 'P3W', {relativeTo: new Date('2023-07-01T00:00:00')}], ['-P21D', '-P3W', {relativeTo: new Date('2023-07-01T00:00:00')}], ['P24D', 'P3W', {relativeTo: new Date('2023-07-01T00:00:00')}], ['-P24D', '-P3W', {relativeTo: new Date('2023-07-01T00:00:00')}], - ['P24DT25H', 'P1M', {relativeTo: new Date('2023-07-01T00:00:00')}], - ['-P24DT25H', '-P1M', {relativeTo: new Date('2023-07-01T00:00:00')}], - ['P25D', 'P1M', {relativeTo: new Date('2023-07-01T00:00:00')}], - ['-P25D', '-P1M', {relativeTo: new Date('2023-07-01T00:00:00')}], - ['P1M1D', 'P1M', {relativeTo: new Date('2023-07-02T00:00:00')}], - ['-P1M1D', '-P1M', {relativeTo: new Date('2023-07-02T00:00:00')}], + ['P25DT36H', 'P1M', {relativeTo: new Date('2023-07-15T18:00:00')}], + ['-P25DT36H', '-P1M', {relativeTo: new Date('2023-07-15T06:00:00')}], + ['P1M1D', 'P1M', {relativeTo: new Date('2023-07-03T00:00:00')}], + ['-P1M1D', '-P1M', {relativeTo: new Date('2023-07-03T00:00:00')}], ['P1M1D', 'P2M', {relativeTo: new Date('2023-07-31T00:00:00')}], ['-P1M1D', '-P2M', {relativeTo: new Date('2023-07-01T00:00:00')}], ['P1D', 'P1D', {relativeTo: new Date('2022-01-01T00:00:00Z')}], @@ -312,8 +315,6 @@ suite('duration', function () { relativeTo: new Date('2022-01-01T00:00:00Z'), }, ], - ['-P27D', '-P27D', {relativeTo: new Date('2023-02-28T00:00:00Z')}], - ['-P27D', '-P1M', {relativeTo: new Date('2023-02-27T00:00:00Z')}], ['P1Y2M1D', 'P2Y', {relativeTo: new Date('2022-12-31T12:00:00.000Z')}], ['-P1Y8D', '-P1Y', {relativeTo: new Date('2024-01-11T12:00:00.000Z')}], ['-P1Y7DT19H43M19S', '-P1Y', {relativeTo: new Date('2024-01-11T12:00:00.000Z')}], @@ -346,142 +347,149 @@ suite('duration', function () { ['PT1H29M', [1, 'hour']], ['PT1H31M', [1, 'hour']], ['PT1H55M', [2, 'hour']], - ['PT20H', [20, 'hour']], - ['PT21H', [1, 'day'], {relativeTo: '2023-01-15T00:00:00Z'}], - ['-PT21H', [-1, 'day'], {relativeTo: '2023-01-15T00:00:00Z'}], - ['P4D', [4, 'day'], {relativeTo: '2023-01-15T00:00:00Z'}], - ['-P4D', [-4, 'day'], {relativeTo: '2023-01-15T00:00:00Z'}], - ['P6D', [1, 'week'], {relativeTo: '2023-01-15T00:00:00Z'}], - ['-P6D', [-1, 'week'], {relativeTo: '2023-01-15T00:00:00Z'}], - ['P2W', [2, 'week'], {relativeTo: '2023-01-15T00:00:00Z'}], - ['-P2W', [-2, 'week'], {relativeTo: '2023-01-15T00:00:00Z'}], - ['P3W3D', [3, 'week'], {relativeTo: '2023-01-15T00:00:00Z'}], - ['-P3W3D', [-3, 'week'], {relativeTo: '2023-01-15T00:00:00Z'}], - ['P3W6D', [1, 'month'], {relativeTo: '2023-01-15T00:00:00Z'}], - ['-P3W6D', [-1, 'month'], {relativeTo: '2023-01-15T00:00:00Z'}], - ['P21D', [3, 'week'], {relativeTo: '2023-01-01T00:00:00Z'}], - ['-P21D', [-3, 'week'], {relativeTo: '2023-01-01T00:00:00Z'}], - ['P24D', [3, 'week'], {relativeTo: '2023-01-01T00:00:00Z'}], - ['-P24D', [-3, 'week'], {relativeTo: '2023-01-01T00:00:00Z'}], - ['P24DT25H', [1, 'month'], {relativeTo: '2023-01-15T00:00:00Z'}], - ['P25D', [1, 'month'], {relativeTo: '2023-01-15T00:00:00Z'}], - ['-P35D', [-1, 'month'], {relativeTo: '2023-02-07T22:22:57Z'}], - ['-P45D', [-1, 'month'], {relativeTo: '2023-02-17T22:22:57Z'}], - ['-P55D', [-1, 'month'], {relativeTo: '2023-02-27T22:22:57Z'}], - ['-P65D', [-3, 'month'], {relativeTo: '2023-02-28T22:22:57Z'}], - ['-P75D', [-3, 'month'], {relativeTo: '2023-03-09T22:22:57Z'}], - ['P1M', [1, 'month'], {relativeTo: '2024-05-31T00:00:00Z'}], - ['-P1M', [-1, 'month'], {relativeTo: '2024-05-31T00:00:00Z'}], - ['-P3M', [-3, 'month'], {relativeTo: '2023-05-30T00:00:00Z'}], + ['PT20H', [20, 'hour'], {relativeTo: '2023-01-15T00:00:00'}], + ['-PT20H', [-20, 'hour'], {relativeTo: '2023-01-15T23:00:00'}], + ['PT20H', [1, 'day'], {relativeTo: '2023-01-15T12:00:00'}], + ['-PT20H', [-1, 'day'], {relativeTo: '2023-01-15T12:00:00'}], + ['P4D', [4, 'day'], {relativeTo: '2023-01-15T00:00:00'}], + ['-P4D', [-4, 'day'], {relativeTo: '2023-01-15T00:00:00'}], + ['P6D', [1, 'week'], {relativeTo: '2023-01-15T00:00:00'}], + ['-P6D', [-1, 'week'], {relativeTo: '2023-01-15T00:00:00'}], + ['P2W', [2, 'week'], {relativeTo: '2023-01-15T00:00:00'}], + ['-P2W', [-2, 'week'], {relativeTo: '2023-01-15T00:00:00'}], + ['P3W3D', [3, 'week'], {relativeTo: '2023-01-15T00:00:00'}], + ['-P3W3D', [-3, 'week'], {relativeTo: '2023-01-15T00:00:00'}], + ['P3W6D', [1, 'month'], {relativeTo: '2023-01-15T00:00:00'}], + ['-P3W6D', [-1, 'month'], {relativeTo: '2023-01-15T00:00:00'}], + ['P21D', [3, 'week'], {relativeTo: '2023-01-01T00:00:00'}], + ['-P21D', [-3, 'week'], {relativeTo: '2023-01-01T00:00:00'}], + ['P24D', [3, 'week'], {relativeTo: '2023-01-01T00:00:00'}], + ['-P24D', [-3, 'week'], {relativeTo: '2023-01-01T00:00:00'}], + ['P25DT36H', [1, 'month'], {relativeTo: '2023-01-15T18:00:00'}], + ['P27D', [1, 'month'], {relativeTo: '2023-01-15T00:00:00'}], + ['-P35D', [-1, 'month'], {relativeTo: '2023-02-07T22:22:57'}], + ['-P45D', [-1, 'month'], {relativeTo: '2023-02-17T22:22:57'}], + ['-P55D', [-1, 'month'], {relativeTo: '2023-02-27T22:22:57'}], + ['-P65D', [-2, 'month'], {relativeTo: '2023-02-28T22:22:57'}], + ['-P75D', [-3, 'month'], {relativeTo: '2023-03-09T22:22:57'}], + ['P1M', [1, 'month'], {relativeTo: '2024-08-30T00:00:00'}], + ['-P1M', [-1, 'month'], {relativeTo: '2024-08-30T00:00:00'}], + ['-P3M', [-3, 'month'], {relativeTo: '2023-08-30T00:00:00'}], [ 'P8M', [8, 'month'], { - relativeTo: new Date('2022-01-01T00:00:00Z'), + relativeTo: new Date('2022-01-01T00:00:00'), }, ], [ '-P8M', [-8, 'month'], { - relativeTo: new Date('2022-12-01T00:00:00Z'), + relativeTo: new Date('2022-12-02T00:00:00'), }, ], [ 'P9M', [9, 'month'], { - relativeTo: new Date('2022-01-01T00:00:00Z'), + relativeTo: new Date('2022-01-01T00:00:00'), }, ], [ '-P9M', [-9, 'month'], { - relativeTo: new Date('2022-12-01T00:00:00Z'), + relativeTo: new Date('2022-12-01T00:00:00'), }, ], - ['P1M1D', [1, 'month'], {relativeTo: new Date('2022-12-01T00:00:00Z')}], - ['P1M1D', [2, 'month'], {relativeTo: new Date('2023-01-31T00:00:00Z')}], - ['P1M30D', [2, 'month'], {relativeTo: new Date('2023-01-31T00:00:00Z')}], + ['P1M1D', [1, 'month'], {relativeTo: new Date('2022-12-01T00:00:00')}], + ['P1M1D', [2, 'month'], {relativeTo: new Date('2023-01-31T00:00:00')}], + ['P1M30D', [2, 'month'], {relativeTo: new Date('2023-01-15T00:00:00')}], [ 'P9M20DT25H', [9, 'month'], { - relativeTo: new Date('2022-01-01T00:00:00Z'), + relativeTo: new Date('2022-01-01T00:00:00'), }, ], [ '-P9M20DT25H', [-10, 'month'], { - relativeTo: new Date('2022-12-01T00:00:00Z'), + relativeTo: new Date('2022-12-01T00:00:00'), }, ], [ 'P9M24DT25H', [9, 'month'], { - relativeTo: new Date('2022-01-01T00:00:00Z'), + relativeTo: new Date('2022-01-01T00:00:00'), }, ], [ '-P9M24DT25H', [-10, 'month'], { - relativeTo: new Date('2022-12-01T00:00:00Z'), + relativeTo: new Date('2022-12-01T00:00:00'), + }, + ], + [ + '-P11M', + [-11, 'month'], + { + relativeTo: new Date('2022-12-02T00:00:00'), }, ], - ['P11M', [11, 'month']], ['P1Y4D', [1, 'year']], [ 'P1Y5M13D', [1, 'year'], { - relativeTo: new Date('2022-01-01T00:00:00Z'), + relativeTo: new Date('2022-01-01T00:00:00'), }, ], [ '-P1Y5M13D', [-1, 'year'], { - relativeTo: new Date('2022-12-01T00:00:00Z'), + relativeTo: new Date('2022-12-01T00:00:00'), }, ], [ 'P1Y5M15D', [1, 'year'], { - relativeTo: new Date('2022-01-01T00:00:00Z'), + relativeTo: new Date('2022-01-01T00:00:00'), }, ], [ '-P1Y5M15D', [-1, 'year'], { - relativeTo: new Date('2022-12-01T00:00:00Z'), + relativeTo: new Date('2022-12-01T00:00:00'), }, ], [ 'P1Y5M20D', [2, 'year'], { - relativeTo: new Date('2022-12-01T00:00:00Z'), + relativeTo: new Date('2022-12-01T00:00:00'), }, ], [ '-P1Y5M20D', [-2, 'year'], { - relativeTo: new Date('2022-01-01T00:00:00Z'), + relativeTo: new Date('2022-01-01T00:00:00'), }, ], - ['P1Y10M', [2, 'year'], {relativeTo: new Date('2022-12-01T00:00:00Z')}], + ['P1Y10M', [2, 'year'], {relativeTo: new Date('2022-12-01T00:00:00')}], [ '-P1Y10M', [-2, 'year'], { - relativeTo: new Date('2022-10-01T00:00:00Z'), + relativeTo: new Date('2022-10-01T00:00:00'), }, ], ]) diff --git a/test/relative-time.js b/test/relative-time.js index c98a1ae..ef0842a 100644 --- a/test/relative-time.js +++ b/test/relative-time.js @@ -450,9 +450,9 @@ suite('relative-time', function () { freezeTime(new Date(2033, 1, 1)) const time = document.createElement('relative-time') time.setAttribute('tense', 'past') - time.setAttribute('datetime', '2023-01-01T00:00:00Z') + time.setAttribute('datetime', '2023-01-01T00:00:00') await Promise.resolve() - assert.equal(time.shadowRoot.textContent, '11 years ago') + assert.equal(time.shadowRoot.textContent, '10 years ago') }) test('rewrites from now past datetime to minutes ago', async () => { @@ -499,7 +499,7 @@ suite('relative-time', function () { time.setAttribute('tense', 'past') time.setAttribute('datetime', '2023-06-01T00:00:00Z') await Promise.resolve() - assert.equal(time.shadowRoot.textContent, '4 months ago') + assert.equal(time.shadowRoot.textContent, '3 months ago') }) test('rewrites from last few days of month to smaller last month', async () => { @@ -1232,72 +1232,84 @@ suite('relative-time', function () { // 40 days in the future { - datetime: '2022-12-03T15:46:00.000Z', + reference: '2022-11-03T15:46:00.000Z', + datetime: '2022-12-13T15:46:00.000Z', tense: 'future', format: 'relative', - expected: 'in 2 months', + expected: 'next month', }, { - datetime: '2022-12-03T15:46:00.000Z', + reference: '2022-11-03T15:46:00.000Z', + datetime: '2022-12-13T15:46:00.000Z', tense: 'past', format: 'relative', expected: 'now', }, { - datetime: '2022-12-03T15:46:00.000Z', + reference: '2022-11-03T15:46:00.000Z', + datetime: '2022-12-13T15:46:00.000Z', format: 'relative', formatStyle: 'narrow', - expected: 'on Dec 3', + expected: 'on Dec 13', }, { - datetime: '2022-12-03T15:46:00.000Z', + reference: '2022-11-03T15:46:00.000Z', + datetime: '2022-12-13T15:46:00.000Z', format: 'relative', precision: 'hour', - expected: 'on Dec 3', + expected: 'on Dec 13', }, { - datetime: '2022-12-03T15:46:00.000Z', + reference: '2022-11-03T15:46:00.000Z', + datetime: '2022-12-13T15:46:00.000Z', format: 'relative', threshold: 'PT0S', - expected: 'on Dec 3', + expected: 'on Dec 13', }, { - datetime: '2022-12-03T15:46:00.000Z', + reference: '2022-11-03T15:46:00.000Z', + datetime: '2022-12-13T15:46:00.000Z', format: 'datetime', - expected: 'Sat, Dec 3', + expected: 'Tue, Dec 13', }, { - datetime: '2022-12-03T15:46:00.000Z', + reference: '2022-11-03T15:46:00.000Z', + datetime: '2022-12-13T15:46:00.000Z', format: 'datetime', weekday: '', month: '', - expected: '3', + expected: '13', }, { - datetime: '2022-12-03T15:46:00.000Z', + reference: '2022-11-03T15:46:00.000Z', + datetime: '2022-12-13T15:46:00.000Z', format: 'duration', - expected: '1 month, 10 days, 1 hour', + expected: '1 month, 10 days', }, { - datetime: '2022-12-03T15:46:00.000Z', + reference: '2022-11-03T15:46:00.000Z', + datetime: '2022-12-13T15:46:00.000Z', format: 'duration', precision: 'minute', - expected: '1 month, 10 days, 1 hour', + expected: '1 month, 10 days', }, { - datetime: '2022-12-03T15:46:00.000Z', + reference: '2022-11-03T15:46:00.000Z', + datetime: '2022-12-13T15:46:00.000Z', format: 'duration', precision: 'day', expected: '1 month, 10 days', }, { - datetime: '2022-12-03T15:46:00.000Z', + reference: '2022-11-03T15:46:00.000Z', + datetime: '2022-12-13T15:46:00.000Z', format: 'duration', tense: 'future', - expected: '1 month, 10 days, 1 hour', + expected: '1 month, 10 days', }, { - datetime: '2022-12-03T15:46:00.000Z', + reference: '2022-11-03T15:46:00.000Z', + datetime: '2022-12-13T15:46:00.000Z', format: 'duration', tense: 'past', expected: '0 seconds', @@ -1349,25 +1361,25 @@ suite('relative-time', function () { { datetime: '2024-10-24T14:46:00.000Z', format: 'duration', - expected: '2 years, 11 days', + expected: '2 years', }, { datetime: '2024-10-24T14:46:00.000Z', format: 'duration', precision: 'minute', - expected: '2 years, 11 days', + expected: '2 years', }, { datetime: '2024-10-24T14:46:00.000Z', format: 'duration', precision: 'day', - expected: '2 years, 11 days', + expected: '2 years', }, { datetime: '2024-10-24T14:46:00.000Z', format: 'duration', tense: 'future', - expected: '2 years, 11 days', + expected: '2 years', }, { datetime: '2024-10-24T14:46:00.000Z', @@ -1799,19 +1811,19 @@ suite('relative-time', function () { { datetime: '2020-10-24T14:46:00.000Z', format: 'duration', - expected: '2 years, 10 days', + expected: '2 years', }, { datetime: '2020-10-24T14:46:00.000Z', format: 'duration', precision: 'minute', - expected: '2 years, 10 days', + expected: '2 years', }, { datetime: '2020-10-24T14:46:00.000Z', format: 'duration', precision: 'day', - expected: '2 years, 10 days', + expected: '2 years', }, { datetime: '2020-10-24T14:46:00.000Z', @@ -1823,11 +1835,11 @@ suite('relative-time', function () { datetime: '2020-10-24T14:46:00.000Z', format: 'duration', tense: 'past', - expected: '2 years, 10 days', + expected: '2 years', }, { reference: '2023-03-23T12:03:00.000Z', - datetime: '2023-03-21T16:03:00.000Z', + datetime: '2023-03-21T15:03:00.000Z', format: 'relative', tense: 'past', expected: '2 days ago', @@ -1977,7 +1989,7 @@ suite('relative-time', function () { expected: '2y', }, { - datetime: '2024-04-01T14:46:00.000Z', + datetime: '2024-09-22T14:46:00.000Z', tense: 'future', format: 'micro', expected: '2y', @@ -2143,7 +2155,7 @@ suite('relative-time', function () { { datetime: '2021-10-30T14:46:00.000Z', format: 'elapsed', - expected: '11m 29d', + expected: '11m 24d', }, { datetime: '2021-10-30T14:46:00.000Z', @@ -2154,7 +2166,7 @@ suite('relative-time', function () { { datetime: '2021-10-29T14:46:00.000Z', format: 'elapsed', - expected: '1y', + expected: '11m 25d', }, // Dates in the past @@ -2481,7 +2493,7 @@ suite('relative-time', function () { datetime: '2022-01-01T12:00:00.000Z', tense: 'past', format: 'micro', - expected: '1y', + expected: '11m', }, { reference: '2022-12-31T12:00:00.000Z', @@ -2499,7 +2511,7 @@ suite('relative-time', function () { }, { reference: '2021-04-24T12:00:00.000Z', - datetime: '2023-02-01T12:00:00.000Z', + datetime: '2023-03-22T12:00:00.000Z', tense: 'future', format: 'micro', expected: '2y', @@ -2512,11 +2524,11 @@ suite('relative-time', function () { expected: '4 years ago', }, { - reference: '2024-12-04T00:00:00.000Z', + reference: '2024-11-14T00:00:00.000Z', datetime: '2024-01-16T00:00:00.000Z', tense: 'past', format: 'auto', - expected: '11 months ago', + expected: '10 months ago', }, ]) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy