Skip to content

Commit d39c73e

Browse files
committed
tweak rounding rules for months
1 parent cce3194 commit d39c73e

File tree

3 files changed

+94
-41
lines changed

3 files changed

+94
-41
lines changed

src/duration.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -150,20 +150,29 @@ export function roundToSingleUnit(duration: Duration, {relativeTo = Date.now()}:
150150
if (hours >= 21) days += Math.round(hours / 24)
151151
if (days || weeks || months || years) hours = 0
152152

153+
const currentYear = relativeTo.getFullYear()
154+
let currentMonth = relativeTo.getMonth()
155+
const currentDate = relativeTo.getDate()
156+
if (days >= 27 || (years + months && days)) {
157+
relativeTo.setDate(currentDate + days * sign)
158+
days = 0
159+
months += Math.abs(
160+
relativeTo.getFullYear() >= currentYear
161+
? relativeTo.getMonth() - currentMonth
162+
: relativeTo.getMonth() - currentMonth - 12,
163+
)
164+
currentMonth = relativeTo.getMonth()
165+
}
166+
153167
if (days >= 6) weeks += Math.round(days / 7)
154168
if (weeks || months || years) days = 0
155169

156170
if (weeks >= 4) months += Math.round(weeks / 4)
157171
if (months || years) weeks = 0
158172

159-
const currentMonth = relativeTo.getMonth()
160-
const delta = sign < 0 ? currentMonth : 12 - currentMonth
161-
if (months && months >= delta) {
162-
years += 1
163-
relativeTo.setFullYear(relativeTo.getFullYear() + sign)
164-
relativeTo.setMonth(0)
165-
months -= delta
166-
years += Math.floor(months / 12)
173+
if (months >= 11 || (years && months)) {
174+
relativeTo.setMonth(relativeTo.getMonth() + months * sign)
175+
years += Math.abs(currentYear - relativeTo.getFullYear())
167176
}
168177
if (years) months = 0
169178

test/duration.ts

Lines changed: 73 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -235,41 +235,72 @@ suite('duration', function () {
235235
['PT1H55M', 'PT2H'],
236236
['PT20H', 'PT20H'],
237237
['PT21H', 'P1D'],
238-
['P4D', 'P4D'],
239-
['P6D', 'P1W'],
240-
['P2W', 'P2W'],
241-
['P3W3D', 'P3W'],
242-
['P3W6D', 'P1M'],
243-
['P21D', 'P3W'],
244-
['P24D', 'P3W'],
245-
['P24DT25H', 'P1M'],
246-
['P25D', 'P1M'],
247-
['P1M1D', 'P1M'],
238+
['P4D', 'P4D', {relativeTo: new Date('2023-07-01T00:00:00')}],
239+
['-P4D', '-P4D', {relativeTo: new Date('2023-07-01T00:00:00')}],
240+
['P6D', 'P1W', {relativeTo: new Date('2023-07-01T00:00:00')}],
241+
['-P6D', '-P1W', {relativeTo: new Date('2023-07-01T00:00:00')}],
242+
['P2W', 'P2W', {relativeTo: new Date('2023-07-01T00:00:00')}],
243+
['-P2W', '-P2W', {relativeTo: new Date('2023-07-01T00:00:00')}],
244+
['P3W3D', 'P3W', {relativeTo: new Date('2023-07-01T00:00:00')}],
245+
['-P3W3D', '-P3W', {relativeTo: new Date('2023-07-01T00:00:00')}],
246+
['P3W6D', 'P1M', {relativeTo: new Date('2023-07-01T00:00:00')}],
247+
['-P3W6D', '-P1M', {relativeTo: new Date('2023-07-01T00:00:00')}],
248+
['P21D', 'P3W', {relativeTo: new Date('2023-07-01T00:00:00')}],
249+
['-P21D', '-P3W', {relativeTo: new Date('2023-07-01T00:00:00')}],
250+
['P24D', 'P3W', {relativeTo: new Date('2023-07-01T00:00:00')}],
251+
['-P24D', '-P3W', {relativeTo: new Date('2023-07-01T00:00:00')}],
252+
['P24DT25H', 'P1M', {relativeTo: new Date('2023-07-01T00:00:00')}],
253+
['-P24DT25H', '-P1M', {relativeTo: new Date('2023-07-01T00:00:00')}],
254+
['P25D', 'P1M', {relativeTo: new Date('2023-07-01T00:00:00')}],
255+
['-P25D', '-P1M', {relativeTo: new Date('2023-07-01T00:00:00')}],
256+
['P1M1D', 'P1M', {relativeTo: new Date('2023-07-02T00:00:00')}],
257+
['-P1M1D', '-P1M', {relativeTo: new Date('2023-07-02T00:00:00')}],
258+
['P1M1D', 'P2M', {relativeTo: new Date('2023-07-31T00:00:00')}],
259+
['-P1M1D', '-P2M', {relativeTo: new Date('2023-07-01T00:00:00')}],
260+
['P1D', 'P1D', {relativeTo: new Date('2022-01-01T00:00:00Z')}],
248261
['-P1D', '-P1D', {relativeTo: new Date('2022-01-01T00:00:00Z')}],
249262
['P8M', 'P8M', {relativeTo: new Date('2022-01-01T00:00:00Z')}],
250263
['-P8M', '-P8M', {relativeTo: new Date('2022-10-01T00:00:00Z')}],
251264
['P9M', 'P9M', {relativeTo: new Date('2022-01-01T00:00:00Z')}],
252265
['-P9M', '-P9M', {relativeTo: new Date('2022-11-01T00:00:00Z')}],
253-
['-P1M', '-P1Y', {relativeTo: new Date('2023-01-01T00:00:00Z')}],
254-
['P1M', 'P1Y', {relativeTo: new Date('2023-12-01T00:00:00Z')}],
266+
['P1M', 'P1M', {relativeTo: new Date('2023-12-01T00:00:00Z')}],
267+
['-P1M', '-P1M', {relativeTo: new Date('2023-01-01T00:00:00Z')}],
268+
['P1M15D', 'P1M', {relativeTo: new Date('2023-12-01T00:00:00Z')}],
269+
['-P1M15D', '-P2M', {relativeTo: new Date('2023-01-01T00:00:00Z')}],
270+
['P1M15D', 'P2M', {relativeTo: new Date('2023-01-18T00:00:00Z')}],
271+
['-P1M15D', '-P2M', {relativeTo: new Date('2023-01-01T00:00:00Z')}],
272+
['P1M15D', 'P2M', {relativeTo: new Date('2023-01-18T00:00:00Z')}],
255273
['-P18M', '-P2Y', {relativeTo: new Date('2023-01-01T00:00:00Z')}],
256274
['P18M', 'P2Y', {relativeTo: new Date('2023-12-01T00:00:00Z')}],
257-
['-P18M', '-P2Y', {relativeTo: new Date('2023-07-01T00:00:00Z')}],
275+
['-P18M', '-P1Y', {relativeTo: new Date('2023-07-01T00:00:00Z')}],
258276
['P18M', 'P2Y', {relativeTo: new Date('2023-07-01T00:00:00Z')}],
259277
['-P18M', '-P1Y', {relativeTo: new Date('2023-08-01T00:00:00Z')}],
260278
['P18M', 'P1Y', {relativeTo: new Date('2023-03-01T00:00:00Z')}],
261-
['-P9M20DT25H', '-P9M', {relativeTo: new Date('2023-11-12T00:00:00Z')}],
262-
['P9M20DT25H', 'P9M', {relativeTo: new Date('2023-01-12T00:00:00Z')}],
279+
[
280+
'-P9M20DT25H',
281+
'-P10M',
282+
{
283+
relativeTo: new Date('2023-11-12T00:00:00Z'),
284+
},
285+
],
286+
['P9M20DT25H', 'P10M', {relativeTo: new Date('2023-01-12T00:00:00Z')}],
263287
['P11M', 'P1Y', {relativeTo: new Date('2022-11-01T00:00:00Z')}],
264288
['-P11M', '-P1Y', {relativeTo: new Date('2022-11-01T00:00:00Z')}],
265289
['P1Y4D', 'P1Y', {relativeTo: new Date('2022-11-01T00:00:00Z')}],
266290
['P1Y5M13D', 'P1Y', {relativeTo: new Date('2023-01-01T00:00:00Z')}],
267291
['P1Y5M15D', 'P1Y', {relativeTo: new Date('2023-01-01T00:00:00Z')}],
268292
['P1Y5M20D', 'P1Y', {relativeTo: new Date('2023-01-01T00:00:00Z')}],
269293
['P1Y10M', 'P2Y', {relativeTo: new Date('2022-11-01T00:00:00Z')}],
270-
['-P1Y10M', '-P2Y', {relativeTo: new Date('2022-11-01T00:00:00Z')}],
294+
['-P1Y10M', '-P1Y', {relativeTo: new Date('2022-11-01T00:00:00Z')}],
271295
['P1Y10M', 'P1Y', {relativeTo: new Date('2022-01-01T00:00:00Z')}],
272296
['-P1Y10M', '-P1Y', {relativeTo: new Date('2022-12-01T00:00:00Z')}],
297+
[
298+
'-P1Y5M20D',
299+
'-P2Y',
300+
{
301+
relativeTo: new Date('2022-01-01T00:00:00Z'),
302+
},
303+
],
273304
])
274305
for (const [input, expected, opts] of roundTests) {
275306
test(`roundToSingleUnit(${input}) === ${expected}`, () => {
@@ -299,16 +330,29 @@ suite('duration', function () {
299330
['PT1H31M', [1, 'hour']],
300331
['PT1H55M', [2, 'hour']],
301332
['PT20H', [20, 'hour']],
302-
['PT21H', [1, 'day']],
303-
['P4D', [4, 'day']],
304-
['P6D', [1, 'week']],
305-
['P2W', [2, 'week']],
306-
['P3W3D', [3, 'week']],
307-
['P3W6D', [1, 'month']],
308-
['P21D', [3, 'week']],
309-
['P24D', [3, 'week']],
310-
['P24DT25H', [1, 'month']],
311-
['P25D', [1, 'month']],
333+
['PT21H', [1, 'day'], {relativeTo: '2023-01-15T00:00:00Z'}],
334+
['-PT21H', [-1, 'day'], {relativeTo: '2023-01-15T00:00:00Z'}],
335+
['P4D', [4, 'day'], {relativeTo: '2023-01-15T00:00:00Z'}],
336+
['-P4D', [-4, 'day'], {relativeTo: '2023-01-15T00:00:00Z'}],
337+
['P6D', [1, 'week'], {relativeTo: '2023-01-15T00:00:00Z'}],
338+
['-P6D', [-1, 'week'], {relativeTo: '2023-01-15T00:00:00Z'}],
339+
['P2W', [2, 'week'], {relativeTo: '2023-01-15T00:00:00Z'}],
340+
['-P2W', [-2, 'week'], {relativeTo: '2023-01-15T00:00:00Z'}],
341+
['P3W3D', [3, 'week'], {relativeTo: '2023-01-15T00:00:00Z'}],
342+
['-P3W3D', [-3, 'week'], {relativeTo: '2023-01-15T00:00:00Z'}],
343+
['P3W6D', [1, 'month'], {relativeTo: '2023-01-15T00:00:00Z'}],
344+
['-P3W6D', [-1, 'month'], {relativeTo: '2023-01-15T00:00:00Z'}],
345+
['P21D', [3, 'week'], {relativeTo: '2023-01-01T00:00:00Z'}],
346+
['-P21D', [-3, 'week'], {relativeTo: '2023-01-01T00:00:00Z'}],
347+
['P24D', [3, 'week'], {relativeTo: '2023-01-01T00:00:00Z'}],
348+
['-P24D', [-3, 'week'], {relativeTo: '2023-01-01T00:00:00Z'}],
349+
['P24DT25H', [1, 'month'], {relativeTo: '2023-01-15T00:00:00Z'}],
350+
['P25D', [1, 'month'], {relativeTo: '2023-01-15T00:00:00Z'}],
351+
['-P35D', [-1, 'month'], {relativeTo: '2023-02-07T22:22:57Z'}],
352+
['-P45D', [-1, 'month'], {relativeTo: '2023-02-17T22:22:57Z'}],
353+
['-P55D', [-1, 'month'], {relativeTo: '2023-02-27T22:22:57Z'}],
354+
['-P65D', [-3, 'month'], {relativeTo: '2023-02-28T22:22:57Z'}],
355+
['-P75D', [-3, 'month'], {relativeTo: '2023-03-09T22:22:57Z'}],
312356
[
313357
'P8M',
314358
[8, 'month'],
@@ -337,7 +381,7 @@ suite('duration', function () {
337381
relativeTo: new Date('2022-12-01T00:00:00Z'),
338382
},
339383
],
340-
['P1M1D', [1, 'month']],
384+
['P1M1D', [1, 'month'], {relativeTo: new Date('2022-12-01T00:00:00Z')}],
341385
[
342386
'P9M20DT25H',
343387
[9, 'month'],
@@ -347,14 +391,14 @@ suite('duration', function () {
347391
],
348392
[
349393
'-P9M20DT25H',
350-
[-9, 'month'],
394+
[-10, 'month'],
351395
{
352396
relativeTo: new Date('2022-12-01T00:00:00Z'),
353397
},
354398
],
355399
[
356400
'P9M24DT25H',
357-
[10, 'month'],
401+
[9, 'month'],
358402
{
359403
relativeTo: new Date('2022-01-01T00:00:00Z'),
360404
},

test/relative-time.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ suite('relative-time', function () {
471471
time.setAttribute('tense', 'past')
472472
time.setAttribute('datetime', '2023-06-01T00:00:00Z')
473473
await Promise.resolve()
474-
assert.equal(time.shadowRoot.textContent, '3 months ago')
474+
assert.equal(time.shadowRoot.textContent, '4 months ago')
475475
})
476476

477477
test('micro formats years', async () => {
@@ -1174,7 +1174,7 @@ suite('relative-time', function () {
11741174
datetime: '2022-12-03T15:46:00.000Z',
11751175
tense: 'future',
11761176
format: 'relative',
1177-
expected: 'next month',
1177+
expected: 'in 2 months',
11781178
},
11791179
{
11801180
datetime: '2022-12-03T15:46:00.000Z',
@@ -2408,14 +2408,14 @@ suite('relative-time', function () {
24082408
datetime: '2024-03-01T12:00:00.000Z',
24092409
tense: 'future',
24102410
format: 'auto',
2411-
expected: 'in 2 years',
2411+
expected: 'in 3 years',
24122412
},
24132413
{
24142414
reference: '2022-12-31T12:00:00.000Z',
24152415
datetime: '2024-03-01T12:00:00.000Z',
24162416
tense: 'future',
24172417
format: 'micro',
2418-
expected: '2y',
2418+
expected: '3y',
24192419
},
24202420
{
24212421
reference: '2021-04-24T12:00:00.000Z',

0 commit comments

Comments
 (0)
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