Skip to content

Commit

Permalink
Merge pull request #271 from github/round-years-using-calendar-years-…
Browse files Browse the repository at this point in the history
…only

round years using calendar years only
  • Loading branch information
keithamus authored Jan 16, 2024
2 parents d0da95b + afdd4ea commit 7e40806
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 21 deletions.
46 changes: 29 additions & 17 deletions src/duration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,33 +151,45 @@ export function roundToSingleUnit(duration: Duration, {relativeTo = Date.now()}:
if (!days && hours >= 21) days += Math.round(hours / 24)
if (days || weeks || months || years) hours = 0

// Resolve calendar dates
const currentYear = relativeTo.getFullYear()
let currentMonth = relativeTo.getMonth()
const currentDate = relativeTo.getDate()
if (days >= 27 || (years + months && days)) {
relativeTo.setDate(currentDate + days * sign)
months += Math.abs(
relativeTo.getFullYear() >= currentYear
? relativeTo.getMonth() - currentMonth
: relativeTo.getMonth() - currentMonth - 12,
)
if (months) {
days = 0
if (days >= 27 || years + months + days) {
const newDate = new Date(relativeTo)
newDate.setFullYear(currentYear + years * sign)
newDate.setMonth(currentMonth + months * sign)
newDate.setDate(currentDate + 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))
const monthsDiff = Math.abs(yearDiff * 12 + monthDiff)
if (daysDiff < 27) {
if (days >= 6) {
weeks += Math.round(days / 7)
days = 0
} else {
days = daysDiff
}
months = years = 0
} else if (monthsDiff < 11) {
months = monthsDiff
years = 0
} else {
months = 0
years = yearDiff * sign
}
if (months || years) days = 0
currentMonth = relativeTo.getMonth()
}

if (days >= 6) weeks += Math.round(days / 7)
if (weeks || months || years) days = 0
if (years) months = 0

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

if (months >= 11 || (years && months)) {
relativeTo.setMonth(relativeTo.getMonth() + months * sign)
years += Math.abs(currentYear - relativeTo.getFullYear())
if (days && weeks && !months && !years) {
weeks += Math.round(days / 7)
days = 0
}
if (years) months = 0

return new Duration(
years * sign,
Expand Down
8 changes: 7 additions & 1 deletion test/duration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ suite('duration', function () {
['P9M20DT25H', 'P10M', {relativeTo: new Date('2023-01-12T00:00:00Z')}],
['P11M', 'P1Y', {relativeTo: new Date('2022-11-01T00:00:00Z')}],
['-P11M', '-P1Y', {relativeTo: new Date('2022-11-01T00:00:00Z')}],
['-P11M15D', '-P1Y', {relativeTo: new Date('2024-01-06T00:00:00')}],
['P1Y4D', 'P1Y', {relativeTo: new Date('2022-11-01T00:00:00Z')}],
['P1Y5M13D', 'P1Y', {relativeTo: new Date('2023-01-01T00:00:00Z')}],
['P1Y5M15D', 'P1Y', {relativeTo: new Date('2023-01-01T00:00:00Z')}],
Expand All @@ -308,7 +309,12 @@ suite('duration', function () {
relativeTo: new Date('2022-01-01T00:00:00Z'),
},
],
['-P27D', '-P1M', {relativeTo: new Date('2023-02-28T00: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')}],
['-P1Y11D', '-P2Y', {relativeTo: new Date('2024-01-11T12:00:00.000Z')}],
])
for (const [input, expected, opts] of roundTests) {
test(`roundToSingleUnit(${input}) === ${expected}`, () => {
Expand Down
13 changes: 10 additions & 3 deletions test/relative-time.js
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ suite('relative-time', function () {
time.setAttribute('datetime', datetime)
time.setAttribute('format', 'micro')
await Promise.resolve()
assert.equal(time.shadowRoot.textContent, '10y')
assert.equal(time.shadowRoot.textContent, '11y')
})

test('micro formats future times', async () => {
Expand Down Expand Up @@ -2416,14 +2416,14 @@ suite('relative-time', function () {
datetime: '2024-03-01T12:00:00.000Z',
tense: 'future',
format: 'auto',
expected: 'in 3 years',
expected: 'in 2 years',
},
{
reference: '2022-12-31T12:00:00.000Z',
datetime: '2024-03-01T12:00:00.000Z',
tense: 'future',
format: 'micro',
expected: '3y',
expected: '2y',
},
{
reference: '2021-04-24T12:00:00.000Z',
Expand All @@ -2432,6 +2432,13 @@ suite('relative-time', function () {
format: 'micro',
expected: '2y',
},
{
reference: '2024-01-04T12:00:00.000Z',
datetime: '2020-02-16T16:16:41.000Z',
tense: 'past',
format: 'auto',
expected: '4 years ago',
},
])

for (const {
Expand Down

0 comments on commit 7e40806

Please sign in to comment.