{"record":{"id":"ae336372d7f5c757","repo":"jeecgboot/JeecgBoot","slug":"hour-values-must-be-between-0-and-23","errorCode":null,"errorMessage":"Hour values must be between 0 and 23","messagePattern":"Hour values must be between 0 and 23","errorType":"validation","errorClass":"ParseException","httpStatus":null,"severity":"error","filePath":"jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java","lineNumber":994,"sourceCode":"        }\n\n        return i;\n    }\n\n    protected void addToSet(int val, int end, int incr, int type)\n            throws ParseException {\n\n        TreeSet<Integer> set = getSet(type);\n\n        if (type == SECOND || type == MINUTE) {\n            if ((val < 0 || val > 59 || end > 59) && (val != ALL_SPEC_INT)) {\n                throw new ParseException(\n                        \"Minute and Second values must be between 0 and 59\",\n                        -1);\n            }\n        } else if (type == HOUR) {\n            if ((val < 0 || val > 23 || end > 23) && (val != ALL_SPEC_INT)) {\n                throw new ParseException(\n                        \"Hour values must be between 0 and 23\", -1);\n            }\n        } else if (type == DAY_OF_MONTH) {\n            if ((val < 1 || val > 31 || end > 31) && (val != ALL_SPEC_INT)\n                    && (val != NO_SPEC_INT)) {\n                throw new ParseException(\n                        \"Day of month values must be between 1 and 31\", -1);\n            }\n        } else if (type == MONTH) {\n            if ((val < 1 || val > 12 || end > 12) && (val != ALL_SPEC_INT)) {\n                throw new ParseException(\n                        \"Month values must be between 1 and 12\", -1);\n            }\n        } else if (type == DAY_OF_WEEK) {\n            if ((val == 0 || val > 7 || end > 7) && (val != ALL_SPEC_INT)\n                    && (val != NO_SPEC_INT)) {\n                throw new ParseException(\n                        \"Day-of-Week values must be between 1 and 7\", -1);","sourceCodeStart":976,"sourceCodeEnd":1012,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java#L976-L1012","documentation":"Thrown by addToSet when a value (or range end) for the HOUR field is less than 0 or greater than 23, unless the value equals ALL_SPEC_INT (sentinel for '*'). Hours use a 24-hour clock starting at 0 (midnight).","triggerScenarios":"A cron expression with an hour field containing a value like 24, 25, or -1 — e.g., hour field '24', '8,25', or range '0-24'.","commonSituations":"Developer uses 24 for midnight (should be 0); uses 12-hour clock notation without AM/PM conversion (e.g., '13' for 1 PM is correct but '24' for midnight is not); dynamic value injection without bounds checking.","solutions":["Ensure all hour values are integers from 0 to 23 (0 = midnight, 23 = 11 PM).","For midnight use 0, not 24 or 12.","Validate dynamically generated hour values against the 0–23 range."],"exampleFix":"// before\nString cron = \"0 0 24 * * ?\";  // 24 is invalid\n// after\nString cron = \"0 0 0 * * ?\";  // midnight (hour 0)","handlingStrategy":"validation","validationCode":"// Validate hour field values are 0-23\nString hourField = fields[2];\nfor (String token : hourField.split(\",\")) {\n    if (token.equals(\"*\") || token.equals(\"?\")) continue;\n    String base = token.split(\"[/\\\\-]\")[0];\n    int val = Integer.parseInt(base);\n    if (val < 0 || val > 23) throw new IllegalArgumentException(\"Hour must be 0-23: \" + val);\n}","typeGuard":"boolean isValidHour(String field) {\n    for (String token : field.split(\",\")) {\n        if (token.equals(\"*\") || token.equals(\"?\")) continue;\n        try {\n            for (String part : token.split(\"[/\\\\-]\")) {\n                int val = Integer.parseInt(part);\n                if (val < 0 || val > 23) return false;\n            }\n        } catch (NumberFormatException e) { return false; }\n    }\n    return true;\n}","tryCatchPattern":"try {\n    CronExpression cron = new CronExpression(expr);\n} catch (ParseException e) {\n    if (e.getMessage().contains(\"Hour values must be between 0 and 23\")) {\n        // fix the hour field value\n    }\n    throw e;\n}","preventionTips":["Use 24-hour notation: 0 for midnight, 23 for 11 PM.","Never use 24 as an hour value.","Bounds-check dynamically generated hour values."],"tags":["cron","validation","scheduling","xxljob","parse"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}