fix: prevent date picker from selecting past times at hour breakpoints (#1814)

The function previously used <= for hour comparisons, which caused it to
return a breakpoint hour even if the current time had passed it. For example,
at 15:54, it would return 15 (3:00 PM), which is in the past.

Now the function checks both hours and minutes:
- If current time is before a breakpoint hour, return that hour
- If current time is exactly at a breakpoint hour with 0 minutes, return that hour
- If current time is past a breakpoint (hour with minutes > 0), return the next breakpoint

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: kolaente <13721712+kolaente@users.noreply.github.com>
This commit is contained in:
Copilot
2025-11-13 10:46:24 +01:00
committed by GitHub
parent 9990a1f60f
commit 7cd3f69096
2 changed files with 51 additions and 6 deletions

View File

@@ -1,24 +1,33 @@
export function calculateNearestHours(currentDate: Date = new Date()): number {
if (currentDate.getHours() <= 9 || currentDate.getHours() > 21) {
const hours = currentDate.getHours()
const minutes = currentDate.getMinutes()
// Helper to check if current time is before a given hour breakpoint
// Returns true if we're before the hour, or at the hour with 0 minutes
const isBeforeOrAt = (breakpoint: number): boolean => {
return hours < breakpoint || (hours === breakpoint && minutes === 0)
}
if (isBeforeOrAt(9) || hours > 21) {
return 9
}
if (currentDate.getHours() <= 12) {
if (isBeforeOrAt(12)) {
return 12
}
if (currentDate.getHours() <= 15) {
if (isBeforeOrAt(15)) {
return 15
}
if (currentDate.getHours() <= 18) {
if (isBeforeOrAt(18)) {
return 18
}
if (currentDate.getHours() <= 21) {
if (isBeforeOrAt(21)) {
return 21
}
// Same case as in the first if, will never be called
// After 21:00 with minutes > 0, return 9 for next day
return 9
}

View File

@@ -90,3 +90,39 @@ test('22:40', () => {
date.setMinutes(0)
expect(calculateNearestHours(date)).toBe(9)
})
// Test cases for the bug: when current time is past a breakpoint hour
test('12:30 should return next breakpoint (15), not current (12)', () => {
const date = new Date()
date.setHours(12)
date.setMinutes(30)
expect(calculateNearestHours(date)).toBe(15)
})
test('15:54 should return next breakpoint (18), not current (15)', () => {
const date = new Date()
date.setHours(15)
date.setMinutes(54)
expect(calculateNearestHours(date)).toBe(18)
})
test('18:45 should return next breakpoint (21), not current (18)', () => {
const date = new Date()
date.setHours(18)
date.setMinutes(45)
expect(calculateNearestHours(date)).toBe(21)
})
test('21:30 should return next day breakpoint (9), not current (21)', () => {
const date = new Date()
date.setHours(21)
date.setMinutes(30)
expect(calculateNearestHours(date)).toBe(9)
})
test('9:01 should return next breakpoint (12), not current (9)', () => {
const date = new Date()
date.setHours(9)
date.setMinutes(1)
expect(calculateNearestHours(date)).toBe(12)
})