Skip to content

Commit f600c99

Browse files
Merge pull request #463 from greymoth-jp/fix/set-month-day-clamp
2 parents 33bf957 + 79f4898 commit f600c99

2 files changed

Lines changed: 24 additions & 12 deletions

File tree

src/methods/set/set.js

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
//these methods wrap around them.
33
import ms from '../../data/milliseconds.js'
44
import { mapping } from '../../data/months.js'
5-
import monthLength from '../../data/monthLengths.js'
65
import walkTo from './walk.js'
76
import { isLeapYear } from '../../fns.js'
7+
import { getMonthLength } from './_model.js'
88

99
const validate = (n) => {
1010
//handle number as a string
@@ -142,14 +142,9 @@ const time = function (s, str, goFwd) {
142142

143143
const date = function (s, n, goFwd) {
144144
n = validate(n)
145-
//avoid setting february 31st
145+
//avoid setting february 31st (leap-aware, same as add())
146146
if (n > 28) {
147-
const month = s.month()
148-
let max = monthLength[month]
149-
// support leap day in february
150-
if (month === 1 && n === 29 && isLeapYear(s.year())) {
151-
max = 29
152-
}
147+
const max = getMonthLength(s.month(), s.year())
153148
if (n > max) {
154149
n = max
155150
}
@@ -183,15 +178,16 @@ const month = function (s, n, goFwd) {
183178
}
184179

185180
let d = s.date()
186-
//there's no 30th of february, etc.
187-
if (d > monthLength[n]) {
181+
//there's no 30th of february, etc. (leap-aware, same as add())
182+
const max = getMonthLength(n, s.year())
183+
if (d > max) {
188184
//make it as close as we can..
189-
d = monthLength[n]
185+
d = max
190186
}
191187
const old = s.clone()
192188
walkTo(s, {
193189
month: n,
194-
d
190+
date: d
195191
})
196192
s = fwdBkwd(s, old, goFwd, 'year') // specify direction
197193
return s.epoch

test/set.test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,3 +222,19 @@ test('time parsing edge cases', (t) => {
222222

223223
t.end()
224224
})
225+
226+
test('month()/date() setters clamp the day to the month length', (t) => {
227+
const iso = (s) => s.format('iso-short')
228+
// .month() must clamp the day to the target month's length
229+
t.equal(iso(spacetime('2020-01-31').month('april')), '2020-04-30', 'jan 31 -> april clamps to the 30th')
230+
t.equal(iso(spacetime('2020-01-31').month('june')), '2020-06-30', 'jan 31 -> june clamps to the 30th')
231+
// leap-year february
232+
t.equal(iso(spacetime('2020-01-31').month('february')), '2020-02-29', 'jan 31 -> feb 29 in a leap year')
233+
t.equal(iso(spacetime('2024-01-31').month('february')), '2024-02-29', 'jan 31 -> feb 29 in a leap year')
234+
t.equal(iso(spacetime('2021-01-31').month('february')), '2021-02-28', 'jan 31 -> feb 28 in a common year')
235+
// .date() must clamp to the same leap-aware length
236+
t.equal(iso(spacetime('2020-02-10').date(31)), '2020-02-29', 'date(31) in a leap february clamps to the 29th')
237+
t.equal(iso(spacetime('2020-02-10').date(30)), '2020-02-29', 'date(30) in a leap february clamps to the 29th')
238+
t.equal(iso(spacetime('2021-02-10').date(31)), '2021-02-28', 'date(31) in a common february clamps to the 28th')
239+
t.end()
240+
})

0 commit comments

Comments
 (0)