{"record":{"id":"bb4a8fa7c888d6b0","repo":"angular/components","slug":"invalid-date-date-for-month-with-index-mon","errorCode":null,"errorMessage":"Invalid date \"${date}\" for month with index \"${month}\".","messagePattern":"Invalid date \"(.+?)\" for month with index \"(.+?)\"\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/material-date-fns-adapter/adapter/date-fns-adapter.ts","lineNumber":152,"sourceCode":"      // creating the Date).\n      if (month < 0 || month > 11) {\n        throw Error(`Invalid month index \"${month}\". Month index has to be between 0 and 11.`);\n      }\n\n      if (date < 1) {\n        throw Error(`Invalid date \"${date}\". Date has to be greater than 0.`);\n      }\n    }\n\n    // Passing the year to the constructor causes year numbers <100 to be converted to 19xx.\n    // To work around this we use `setFullYear` and `setHours` instead.\n    const result = new Date();\n    result.setFullYear(year, month, date);\n    result.setHours(0, 0, 0, 0);\n\n    // Check that the date wasn't above the upper bound for the month, causing the month to overflow\n    if (result.getMonth() != month && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n      throw Error(`Invalid date \"${date}\" for month with index \"${month}\".`);\n    }\n\n    return result;\n  }\n\n  today(): Date {\n    return new Date();\n  }\n\n  parse(value: unknown, parseFormat: string | string[]): Date | null {\n    return this._parse(value, parseFormat);\n  }\n\n  format(date: Date, displayFormat: string): string {\n    if (!this.isValid(date)) {\n      throw Error('DateFnsAdapter: Cannot format invalid date.');\n    }\n","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/material-date-fns-adapter/adapter/date-fns-adapter.ts#L134-L170","documentation":"After building the Date via setFullYear(year, month, date), DateFnsAdapter checks whether the resulting month still equals the requested month. If the day exceeded the month's length (e.g. Feb 30), JavaScript's Date overflows into the next month, and the adapter throws to catch it (dev mode).","triggerScenarios":"createDate(2024, 1, 30) (Feb 30), createDate(year, 3, 31) (Apr 31), or any day number greater than the target month's day count — including February on non-leap years (Feb 29 in 2023).","commonSituations":"Building dates from separate user-selected year/month/day fields without validating day against the month; hard-coded day values like 31; leap-year bugs with Feb 29.","solutions":["Validate the day against the actual days in the month before calling createDate (use date-fns getDaysInMonth logic).","Clamp the day: Math.min(day, daysInMonth(year, month)).","For 'end of month' semantics use date-fns endOfMonth instead of day 31.","Fix leap-year handling for February dates."],"exampleFix":"// before\nconst d = this.adapter.createDate(2024, 1, 30); // Feb 30 -> throws\n// after\nconst day = Math.min(30, 29); // daysInMonth(2024, 1) = 29\nconst d = this.adapter.createDate(2024, 1, day);","handlingStrategy":"validation","validationCode":"const daysInMonth = new Date(year, month + 1, 0).getDate();\nif (date < 1 || date > daysInMonth) {\n  throw new RangeError(`date ${date} out of range for month ${month} (1-${daysInMonth})`);\n}\nconst d = adapter.createDate(year, month, date);","typeGuard":"function isValidDateForMonth(y: number, m: number, d: number): boolean {\n  return d >= 1 && d <= new Date(y, m + 1, 0).getDate();\n}","tryCatchPattern":"try {\n  return this.adapter.createDate(year, month, day);\n} catch (e) {\n  if ((e as Error).message.startsWith('Invalid date \"') && e.message.includes('for month')) {\n    const max = new Date(year, month + 1, 0).getDate();\n    return this.adapter.createDate(year, month, Math.min(day, max));\n  }\n  throw e;\n}","preventionTips":["Clamp day with days-in-month when combining separate year/month/day inputs","Handle Feb 29 explicitly (isLeapYear checks) in calendar logic","Use date-fns endOfMonth for 'last day of month' semantics","Validate user-composed dates before persistence, not only at creation"],"tags":["date","validation","material","date-fns","overflow"],"backgroundTag":"invalid-date-argument","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}