{"record":{"id":"cae49205c35da3b6","repo":"ionic-team/ionic-framework","slug":"invalid-hour-cycle-hourcycle-cae492","errorCode":null,"errorMessage":"Invalid hour cycle \"${hourCycle}\"","messagePattern":"Invalid hour cycle \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"core/src/components/datetime/utils/helpers.ts","lineNumber":69,"sourceCode":"  }\n\n  /**\n   * Midnight for h11 starts at 0:00am\n   * Midnight for h12 starts at 12:00am\n   * Midnight for h23 starts at 00:00\n   * Midnight for h24 starts at 24:00\n   */\n  switch (hour.value) {\n    case '0':\n      return 'h11';\n    case '12':\n      return 'h12';\n    case '00':\n      return 'h23';\n    case '24':\n      return 'h24';\n    default:\n      throw new Error(`Invalid hour cycle \"${hourCycle}\"`);\n  }\n};\n\n/**\n * Determine if the hour cycle uses a 24-hour format.\n * Returns true for h23 and h24. Returns false otherwise.\n * If you don't know the hourCycle, use getHourCycle above\n * and pass the result into this function.\n */\nexport const is24Hour = (hourCycle: DatetimeHourCycle) => {\n  return hourCycle === 'h23' || hourCycle === 'h24';\n};\n\n/**\n * Given a date object, returns the number\n * of days in that month.\n * Month value begin at 1, not 0.\n * i.e. January = month 1.","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/ionic-team/ionic-framework/blob/625f9c38ad8c5db8a6c12df5c1622a36da90f9e3/core/src/components/datetime/utils/helpers.ts#L51-L87","documentation":"Thrown by getHourCycle() on the same Intl fallback path as error 2, but one step further: the hour part was found, yet its string value was not '0', '12', '00', or '24'. Note the message interpolates the optional hourCycle parameter (which is undefined on this path), so it renders as `Invalid hour cycle \"undefined\"` - a mildly misleading message, since the real offender is hour.value, not hourCycle.","triggerScenarios":"Intl.DateTimeFormat(locale, {hour:'numeric'}).formatToParts(midnightDate) returns an hour part whose value is something other than the four expected midnight representations - for example leading-zero differences like ' 0', locale-specific numerals (Arabic-Indic digits), or a non-midnight value because the test date resolved to a different hour in that timezone/locale.","commonSituations":"Locales with non-Latin digit output; environments that normalize/trim hour strings differently; a locale whose default hour formatting does not match the four hardcoded midnight snapshots; ICU data variants between Node versions.","solutions":["Provide an explicit hourCycle prop to ion-datetime to avoid the heuristic detection entirely.","Embed the cycle in the locale string using the Unicode extension, e.g. 'en-US-u-hc-h23', which resolvedOptions().hourCycle will then return and short-circuit the fallback.","Ensure full ICU data is available so Intl hour output matches the expected Latin-digit snapshots.","If you maintain a fork, normalize hour.value (trim, convert digits) before the switch."],"exampleFix":"// before\n<ion-datetime locale=\"ar-EG\"></ion-datetime> <!-- Intl may emit non-Latin digits -->\n\n// after\n<ion-datetime locale=\"ar-EG-u-hc-h23\" hour-cycle=\"h23\"></ion-datetime>","handlingStrategy":"fallback","validationCode":"// Prefer embedding the cycle in the locale so resolvedOptions() short-circuits the fallback:\nconst locale = baseLocale + '-u-hc-h23';\n// then Intl.DateTimeFormat(locale).resolvedOptions().hourCycle === 'h23'","typeGuard":"function localeDeclaresHourCycle(locale: string): boolean {\n  try {\n    return new Intl.DateTimeFormat(locale, { hour: 'numeric' }).resolvedOptions().hourCycle !== undefined;\n  } catch {\n    return false;\n  }\n}","tryCatchPattern":"try {\n  cycle = getHourCycle(locale);\n} catch (e) {\n  if (e instanceof Error && /Invalid hour cycle/.test(e.message)) {\n    cycle = 'h23'; // deterministic fallback\n  } else { throw e; }\n}","preventionTips":["Use the Unicode -u-hc-* extension in locale strings to avoid the heuristic path.","Provide explicit hourCycle on ion-datetime in non-Latin-digit locales.","Ensure full ICU data is present so hour output matches expected snapshots."],"tags":["datetime","hour-cycle","intl","locale","i18n","runtime"],"backgroundTag":null,"analyzedSha":"625f9c38ad8c5db8a6c12df5c1622a36da90f9e3","analyzedAt":"2026-08-12T16:00:25.413Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}