{"record":{"id":"1679105a6da593b6","repo":"angular/components","slug":"invalid-hours-hours-hours-value-must-be-betw","errorCode":null,"errorMessage":"Invalid hours \"${hours}\". Hours value must be between 0 and 23.","messagePattern":"Invalid hours \"(.+?)\"\\. Hours value must be between 0 and 23\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/material-date-fns-adapter/adapter/date-fns-adapter.ts","lineNumber":223,"sourceCode":"    return super.deserialize(value);\n  }\n\n  isDateInstance(obj: unknown): obj is Date {\n    return isDate(obj);\n  }\n\n  isValid(date: Date): boolean {\n    return isValid(date);\n  }\n\n  invalid(): Date {\n    return new Date(NaN);\n  }\n\n  override setTime(target: Date, hours: number, minutes: number, seconds: number): Date {\n    if (typeof ngDevMode === 'undefined' || ngDevMode) {\n      if (hours < 0 || hours > 23) {\n        throw Error(`Invalid hours \"${hours}\". Hours value must be between 0 and 23.`);\n      }\n\n      if (minutes < 0 || minutes > 59) {\n        throw Error(`Invalid minutes \"${minutes}\". Minutes value must be between 0 and 59.`);\n      }\n\n      if (seconds < 0 || seconds > 59) {\n        throw Error(`Invalid seconds \"${seconds}\". Seconds value must be between 0 and 59.`);\n      }\n    }\n\n    return set(this.clone(target), {hours, minutes, seconds, milliseconds: 0});\n  }\n\n  override getHours(date: Date): number {\n    return getHours(date);\n  }\n","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/material-date-fns-adapter/adapter/date-fns-adapter.ts#L205-L241","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nthis.adapter.setTime(target, 24, 0, 0); // throws\n// after\nthis.adapter.setTime(this.adapter.addCalendarDays(target, 1), 0, 0, 0);","handlingStrategy":"validation","validationCode":"if (!Number.isInteger(hours) || hours < 0 || hours > 23) {\n  throw new RangeError(`hours must be 0-23, got ${hours}`);\n}\nconst d = adapter.setTime(target, hours, minutes, seconds);","typeGuard":"function isValidHour(h: unknown): h is number {\n  return typeof h === 'number' && Number.isInteger(h) && h >= 0 && h <= 23;\n}","tryCatchPattern":"try {\n  return this.adapter.setTime(t, h, m, s);\n} catch (e) {\n  if ((e as Error).message.startsWith('Invalid hours')) {\n    return this.adapter.setTime(t, Math.min(Math.max(h, 0), 23), m, s);\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["date","time","validation","material","date-fns","dev-mode"],"backgroundTag":"invalid-time-component","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}