Skip to content

Commit 76e8d0a

Browse files
Fix time changing when switching calendar dates
1 parent 0948566 commit 76e8d0a

File tree

2 files changed

+38
-31
lines changed

2 files changed

+38
-31
lines changed

src/lib/DatePicker.svelte

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
getCalendarDays,
66
type CalendarDay,
77
applyTimePrecision,
8+
clampDate,
9+
clamp,
810
} from './date-utils.js'
911
import { getInnerLocale, type Locale } from './locale.js'
1012
import { createEventDispatcher } from 'svelte'
@@ -68,31 +70,6 @@
6870
} else if (value && isDisabledDate?.(value)) {
6971
setValue(toValidDate(browseDate, value, min, max, isDisabledDate))
7072
}
71-
function clamp(d: Date, min: Date, max: Date) {
72-
if (d > max) {
73-
return cloneDate(max)
74-
} else if (d < min) {
75-
return cloneDate(min)
76-
} else {
77-
return cloneDate(d)
78-
}
79-
}
80-
function clampDate(d: Date, min: Date, max: Date) {
81-
const limit = clamp(d, min, max)
82-
if (limit.getTime() !== d.getTime()) {
83-
d = new Date(
84-
limit.getFullYear(),
85-
limit.getMonth(),
86-
limit.getDate(),
87-
d.getHours(),
88-
d.getMinutes(),
89-
d.getSeconds(),
90-
d.getMilliseconds(),
91-
)
92-
d = clamp(d, min, max)
93-
}
94-
return d
95-
}
9673
9774
/** The date shown in the popup when none is selected */
9875
let browseDate = value ? cloneDate(value) : cloneDate(clampDate(defaultDate, min, max))

src/lib/date-utils.ts

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,20 +114,21 @@ export function toValidDate(
114114
if (oldDate > newDate) {
115115
adjustDate(adjustedDate, -1, minDate, maxDate, isDisabledDate)
116116
if (adjustedDate < minDate) {
117-
adjustedDate = cloneDate(minDate)
117+
adjustedDate = clampDate(adjustedDate, minDate, maxDate)
118118
// Adjusts the date one more time if the min date is disabled, to ensure a valid, enabled date is selected
119119
adjustDate(adjustedDate, 1, minDate, maxDate, isDisabledDate)
120120
}
121-
return adjustedDate
122-
}
123-
if (adjustedDate >= oldDate) {
121+
} else if (adjustedDate >= oldDate) {
124122
adjustDate(adjustedDate, 1, minDate, maxDate, isDisabledDate)
125123
if (adjustedDate > maxDate) {
126-
adjustedDate = cloneDate(maxDate)
124+
adjustedDate = clampDate(adjustedDate, minDate, maxDate)
127125
// Adjusts the date one more time if the max date is disabled, to ensure a valid, enabled date is selected
128126
adjustDate(adjustedDate, -1, minDate, maxDate, isDisabledDate)
129127
}
130-
return adjustedDate
128+
}
129+
// Finally, clamp the time
130+
if (adjustedDate < minDate || adjustedDate > maxDate) {
131+
adjustedDate = clamp(adjustedDate, minDate, maxDate)
131132
}
132133
return adjustedDate
133134
}
@@ -148,3 +149,32 @@ function adjustDate(
148149
loopCount++
149150
}
150151
}
152+
153+
export function clamp(value: Date, min: Date, max: Date) {
154+
if (value > max) {
155+
return cloneDate(max)
156+
} else if (value < min) {
157+
return cloneDate(min)
158+
} else {
159+
return cloneDate(value)
160+
}
161+
}
162+
export function clampDate(value: Date, min: Date, max: Date) {
163+
const limit = clamp(value, min, max)
164+
value = new Date(
165+
limit.getFullYear(),
166+
limit.getMonth(),
167+
limit.getDate(),
168+
value.getHours(),
169+
value.getMinutes(),
170+
value.getSeconds(),
171+
value.getMilliseconds(),
172+
)
173+
if (value > max) {
174+
value.setDate(max.getDate())
175+
}
176+
if (value < min) {
177+
value.setDate(min.getDate())
178+
}
179+
return value
180+
}

0 commit comments

Comments
 (0)