{"record":{"id":"f1e42fca90bfd77e","repo":"OpenRefine/OpenRefine","slug":"bad-hour-val","errorCode":null,"errorMessage":"Bad hour <val>","messagePattern":"Bad hour <val>","errorType":"exception","errorClass":"CalendarParserException","httpStatus":null,"severity":"error","filePath":"modules/core/src/main/java/com/google/refine/expr/util/CalendarParser.java","lineNumber":380,"sourceCode":"     * Set the hour value.\n     * \n     * @param val\n     *            hour value\n     * \n     * @throws CalendarParserException\n     *             if the value is not a valid hour\n     */\n    void setHour(int val) throws CalendarParserException {\n        final int tmpHour;\n        if (timePostMeridian) {\n            tmpHour = val + 12;\n            timePostMeridian = false;\n        } else {\n            tmpHour = val;\n        }\n\n        if (tmpHour < 0 || tmpHour > 23) {\n            throw new CalendarParserException(\"Bad hour \" + val);\n        }\n\n        hour = tmpHour;\n    }\n\n    /**\n     * Set the millisecond value.\n     * \n     * @param val\n     *            millisecond value\n     * \n     * @throws CalendarParserException\n     *             if the value is not a valid millisecond\n     */\n    void setMillisecond(int val) throws CalendarParserException {\n        if (val < 0 || val > 999) {\n            throw new CalendarParserException(\"Bad millisecond \" + val);\n        }","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/OpenRefine/OpenRefine/blob/a946177e049f3b0644261661db36cbb0c81ccf8a/modules/core/src/main/java/com/google/refine/expr/util/CalendarParser.java#L362-L398","documentation":"setHour() normalizes AM/PM handling then validates the hour, throwing CalendarParserException \"Bad hour\" when the resulting 24-hour value is outside 0-23. It guards time parsing during date-string interpretation.","triggerScenarios":"A time token with hour 24 or higher (e.g. \"24:30\") that is neither a 12-hour clock value adjusted by AM/PM nor a valid 24-hour hour; garbage numeric tokens reaching setHour.","commonSituations":"User data using \"24:00\" for midnight instead of \"00:00\"; hour/minute fields swapped; OCR'd or hand-entered times with impossible hours like 27:15.","solutions":["Convert 24:xx times to 00:xx in the source data","Ensure AM/PM markers are present and correct for 12-hour times so the parser can normalize","Pre-validate hour range (0-23) before invoking the parser","Catch CalendarParserException and treat the cell as an invalid date"],"exampleFix":"// before\nString t = \"24:15\"; // Bad hour 24\n// after\nString t = \"00:15\"; // midnight in 24-hour notation","handlingStrategy":"validation","validationCode":"if (hour < 0 || hour > 23) throw new IllegalArgumentException(\"hour out of range: \" + hour);","typeGuard":null,"tryCatchPattern":"try {\n    parser.setHour(hour);\n} catch (CalendarParserException e) {\n    log.error(\"Invalid hour token: {}\", e.getMessage());\n}","preventionTips":["Normalize 24:xx to 00:xx before parsing","Ensure AM/PM markers are present for 12-hour times","Range-check hours before invoking parser"],"tags":["date","time","parsing","validation"],"backgroundTag":"value-out-of-range","analyzedSha":"a946177e049f3b0644261661db36cbb0c81ccf8a","analyzedAt":"2026-09-08T10:21:27.735Z","contentChangedAt":"2026-09-08T10:21:27.735Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}