angular/components · error
Invalid hours "${hours}". Hours value must be between 0 and
Error message
Invalid hours "${hours}". Hours value must be between 0 and 23. What it means
DateFnsAdapter.setTime validates the hours argument (must be 0–23) and throws in dev mode when out of range. This guards against JavaScript's silent time-overflow (e.g. hour 24 rolls to the next day).
Source
Thrown at src/material-date-fns-adapter/adapter/date-fns-adapter.ts:223
return super.deserialize(value);
}
isDateInstance(obj: unknown): obj is Date {
return isDate(obj);
}
isValid(date: Date): boolean {
return isValid(date);
}
invalid(): Date {
return new Date(NaN);
}
override setTime(target: Date, hours: number, minutes: number, seconds: number): Date {
if (typeof ngDevMode === 'undefined' || ngDevMode) {
if (hours < 0 || hours > 23) {
throw Error(`Invalid hours "${hours}". Hours value must be between 0 and 23.`);
}
if (minutes < 0 || minutes > 59) {
throw Error(`Invalid minutes "${minutes}". Minutes value must be between 0 and 59.`);
}
if (seconds < 0 || seconds > 59) {
throw Error(`Invalid seconds "${seconds}". Seconds value must be between 0 and 59.`);
}
}
return set(this.clone(target), {hours, minutes, seconds, milliseconds: 0});
}
override getHours(date: Date): number {
return getHours(date);
}
View on GitHub (pinned to 0411926e7d)
Solutions
- Normalize hours into 0–23 before calling setTime (convert 12-hour with % 12 + meridiem offset).
- Use addCalendarHours for arithmetic that may exceed 23 instead of setTime.
- Validate time-picker input ranges before applying.
- Ensure empty inputs are rejected rather than passed through.
Example fix
// before this.adapter.setTime(target, 24, 0, 0); // throws // after this.adapter.setTime(this.adapter.addCalendarDays(target, 1), 0, 0, 0);
Defensive patterns
Strategy: validation
Validate before calling
if (!Number.isInteger(hours) || hours < 0 || hours > 23) {
throw new RangeError(`hours must be 0-23, got ${hours}`);
}
const d = adapter.setTime(target, hours, minutes, seconds); Type guard
function isValidHour(h: unknown): h is number {
return typeof h === 'number' && Number.isInteger(h) && h >= 0 && h <= 23;
} Try / catch
try {
return this.adapter.setTime(t, h, m, s);
} catch (e) {
if ((e as Error).message.startsWith('Invalid hours')) {
return this.adapter.setTime(t, Math.min(Math.max(h, 0), 23), m, s);
}
throw e;
} Prevention
- Convert 12-hour input with (h % 12) + (pm ? 12 : 0) before setTime
- Use addCalendarHours for durations exceeding 23
- Validate time-picker outputs before applying
- Treat NaN/undefined inputs as errors at the form layer
When it happens
Trigger: Calling adapter.setTime(target, hours, minutes, seconds) with hours < 0 or hours > 23 — e.g. 12-hour-clock input passed without conversion (12 PM as 12 is fine, but 24 for midnight), or unvalidated time-picker input.
Common situations: Converting 12-hour to 24-hour time incorrectly; duration arithmetic (hours sum > 23) fed directly to setTime; empty form fields yielding NaN or out-of-range numbers.
Related errors
- Invalid minutes "${minutes}". Minutes value must be between
- Invalid seconds "${seconds}". Seconds value must be between
- Invalid month index "${month}". Month index has to be betwee
- Invalid date "${date}". Date has to be greater than 0.
- Invalid date "${date}" for month with index "${month}".
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/1679105a6da593b6.
Report an issue: GitHub.