Skip to content

Commit 7e40806

Browse files
authored
Merge pull request #271 from github/round-years-using-calendar-years-only
round years using calendar years only
2 parents d0da95b + afdd4ea commit 7e40806

File tree

3 files changed

+46
-21
lines changed

3 files changed

+46
-21
lines changed

src/duration.ts

+29-17
Original file line numberDiff line numberDiff line change
@@ -151,33 +151,45 @@ export function roundToSingleUnit(duration: Duration, {relativeTo = Date.now()}:
151151
if (!days && hours >= 21) days += Math.round(hours / 24)
152152
if (days || weeks || months || years) hours = 0
153153

154+
// Resolve calendar dates
154155
const currentYear = relativeTo.getFullYear()
155156
let currentMonth = relativeTo.getMonth()
156157
const currentDate = relativeTo.getDate()
157-
if (days >= 27 || (years + months && days)) {
158-
relativeTo.setDate(currentDate + days * sign)
159-
months += Math.abs(
160-
relativeTo.getFullYear() >= currentYear
161-
? relativeTo.getMonth() - currentMonth
162-
: relativeTo.getMonth() - currentMonth - 12,
163-
)
164-
if (months) {
165-
days = 0
158+
if (days >= 27 || years + months + days) {
159+
const newDate = new Date(relativeTo)
160+
newDate.setFullYear(currentYear + years * sign)
161+
newDate.setMonth(currentMonth + months * sign)
162+
newDate.setDate(currentDate + days * sign)
163+
const yearDiff = newDate.getFullYear() - relativeTo.getFullYear()
164+
const monthDiff = newDate.getMonth() - relativeTo.getMonth()
165+
const daysDiff = Math.abs(Math.round((Number(newDate) - Number(relativeTo)) / 86400000))
166+
const monthsDiff = Math.abs(yearDiff * 12 + monthDiff)
167+
if (daysDiff < 27) {
168+
if (days >= 6) {
169+
weeks += Math.round(days / 7)
170+
days = 0
171+
} else {
172+
days = daysDiff
173+
}
174+
months = years = 0
175+
} else if (monthsDiff < 11) {
176+
months = monthsDiff
177+
years = 0
178+
} else {
179+
months = 0
180+
years = yearDiff * sign
166181
}
182+
if (months || years) days = 0
167183
currentMonth = relativeTo.getMonth()
168184
}
169-
170-
if (days >= 6) weeks += Math.round(days / 7)
171-
if (weeks || months || years) days = 0
185+
if (years) months = 0
172186

173187
if (weeks >= 4) months += Math.round(weeks / 4)
174188
if (months || years) weeks = 0
175-
176-
if (months >= 11 || (years && months)) {
177-
relativeTo.setMonth(relativeTo.getMonth() + months * sign)
178-
years += Math.abs(currentYear - relativeTo.getFullYear())
189+
if (days && weeks && !months && !years) {
190+
weeks += Math.round(days / 7)
191+
days = 0
179192
}
180-
if (years) months = 0
181193

182194
return new Duration(
183195
years * sign,

test/duration.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ suite('duration', function () {
293293
['P9M20DT25H', 'P10M', {relativeTo: new Date('2023-01-12T00:00:00Z')}],
294294
['P11M', 'P1Y', {relativeTo: new Date('2022-11-01T00:00:00Z')}],
295295
['-P11M', '-P1Y', {relativeTo: new Date('2022-11-01T00:00:00Z')}],
296+
['-P11M15D', '-P1Y', {relativeTo: new Date('2024-01-06T00:00:00')}],
296297
['P1Y4D', 'P1Y', {relativeTo: new Date('2022-11-01T00:00:00Z')}],
297298
['P1Y5M13D', 'P1Y', {relativeTo: new Date('2023-01-01T00:00:00Z')}],
298299
['P1Y5M15D', 'P1Y', {relativeTo: new Date('2023-01-01T00:00:00Z')}],
@@ -308,7 +309,12 @@ suite('duration', function () {
308309
relativeTo: new Date('2022-01-01T00:00:00Z'),
309310
},
310311
],
311-
['-P27D', '-P1M', {relativeTo: new Date('2023-02-28T00:00:00Z')}],
312+
['-P27D', '-P27D', {relativeTo: new Date('2023-02-28T00:00:00Z')}],
313+
['-P27D', '-P1M', {relativeTo: new Date('2023-02-27T00:00:00Z')}],
314+
['P1Y2M1D', 'P2Y', {relativeTo: new Date('2022-12-31T12:00:00.000Z')}],
315+
['-P1Y8D', '-P1Y', {relativeTo: new Date('2024-01-11T12:00:00.000Z')}],
316+
['-P1Y7DT19H43M19S', '-P1Y', {relativeTo: new Date('2024-01-11T12:00:00.000Z')}],
317+
['-P1Y11D', '-P2Y', {relativeTo: new Date('2024-01-11T12:00:00.000Z')}],
312318
])
313319
for (const [input, expected, opts] of roundTests) {
314320
test(`roundToSingleUnit(${input}) === ${expected}`, () => {

test/relative-time.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ suite('relative-time', function () {
482482
time.setAttribute('datetime', datetime)
483483
time.setAttribute('format', 'micro')
484484
await Promise.resolve()
485-
assert.equal(time.shadowRoot.textContent, '10y')
485+
assert.equal(time.shadowRoot.textContent, '11y')
486486
})
487487

488488
test('micro formats future times', async () => {
@@ -2416,14 +2416,14 @@ suite('relative-time', function () {
24162416
datetime: '2024-03-01T12:00:00.000Z',
24172417
tense: 'future',
24182418
format: 'auto',
2419-
expected: 'in 3 years',
2419+
expected: 'in 2 years',
24202420
},
24212421
{
24222422
reference: '2022-12-31T12:00:00.000Z',
24232423
datetime: '2024-03-01T12:00:00.000Z',
24242424
tense: 'future',
24252425
format: 'micro',
2426-
expected: '3y',
2426+
expected: '2y',
24272427
},
24282428
{
24292429
reference: '2021-04-24T12:00:00.000Z',
@@ -2432,6 +2432,13 @@ suite('relative-time', function () {
24322432
format: 'micro',
24332433
expected: '2y',
24342434
},
2435+
{
2436+
reference: '2024-01-04T12:00:00.000Z',
2437+
datetime: '2020-02-16T16:16:41.000Z',
2438+
tense: 'past',
2439+
format: 'auto',
2440+
expected: '4 years ago',
2441+
},
24352442
])
24362443

24372444
for (const {

0 commit comments

Comments
 (0)