Skip to content

Commit 183f034

Browse files
Merge pull request #461 from spokodev/fix-leap-month-add
fix(add): clamp month arithmetic to the leap-aware month length
2 parents 164af45 + 4d34a00 commit 183f034

3 files changed

Lines changed: 13 additions & 4 deletions

File tree

src/methods/add.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import walkTo from './set/walk.js'
22
import ms from '../data/milliseconds.js'
3-
import monthLength from '../data/monthLengths.js'
4-
import { months, daysBack, days } from './set/_model.js'
3+
import { months, daysBack, days, getMonthLength } from './set/_model.js'
54
import { normalize } from '../fns.js'
65
// this logic is a bit of a mess,
76
// but briefly:
@@ -153,7 +152,8 @@ const addMethods = (SpaceTime) => {
153152
}
154153
//keep current date, unless the month doesn't have it.
155154
if (keepDate[unit]) {
156-
const max = monthLength[want.month]
155+
const year = want.year !== undefined ? want.year : old.year()
156+
const max = getMonthLength(want.month, year)
157157
want.date = old.date()
158158
if (want.date > max) {
159159
want.date = max

src/methods/set/_model.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import monthLength from '../../data/monthLengths.js'
22
import { isLeapYear } from '../../fns.js'
33

4-
const getMonthLength = function (month, year) {
4+
export const getMonthLength = function (month, year) {
55
if (month === 1 && isLeapYear(year)) {
66
return 29
77
}

test/add.test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,12 @@ test('year-tricky', (t) => {
159159
t.equal(b.year(), 2015, 'year-last')
160160
t.end()
161161
})
162+
163+
test('add/subtract month clamps to the leap-aware month length', (t) => {
164+
t.equal(spacetime('2020-01-31').add(1, 'month').format('iso-short'), '2020-02-29', 'jan 31 + 1mo -> feb 29 (leap)')
165+
t.equal(spacetime('2024-01-31').add(1, 'month').format('iso-short'), '2024-02-29', 'jan 31 + 1mo -> feb 29 (leap)')
166+
t.equal(spacetime('2000-01-31').add(1, 'month').format('iso-short'), '2000-02-29', 'jan 31 + 1mo -> feb 29 (400-year leap)')
167+
t.equal(spacetime('2021-01-31').add(1, 'month').format('iso-short'), '2021-02-28', 'jan 31 + 1mo -> feb 28 (common year)')
168+
t.equal(spacetime('2020-03-31').subtract(1, 'month').format('iso-short'), '2020-02-29', 'mar 31 - 1mo -> feb 29 (leap)')
169+
t.end()
170+
})

0 commit comments

Comments
 (0)