jeecgboot/JeecgBoot · error · ParseException

Hour values must be between 0 and 23

Error message

Hour values must be between 0 and 23

What it means

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).

Source

Thrown at jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java:994

        }

        return i;
    }

    protected void addToSet(int val, int end, int incr, int type)
            throws ParseException {

        TreeSet<Integer> set = getSet(type);

        if (type == SECOND || type == MINUTE) {
            if ((val < 0 || val > 59 || end > 59) && (val != ALL_SPEC_INT)) {
                throw new ParseException(
                        "Minute and Second values must be between 0 and 59",
                        -1);
            }
        } else if (type == HOUR) {
            if ((val < 0 || val > 23 || end > 23) && (val != ALL_SPEC_INT)) {
                throw new ParseException(
                        "Hour values must be between 0 and 23", -1);
            }
        } else if (type == DAY_OF_MONTH) {
            if ((val < 1 || val > 31 || end > 31) && (val != ALL_SPEC_INT)
                    && (val != NO_SPEC_INT)) {
                throw new ParseException(
                        "Day of month values must be between 1 and 31", -1);
            }
        } else if (type == MONTH) {
            if ((val < 1 || val > 12 || end > 12) && (val != ALL_SPEC_INT)) {
                throw new ParseException(
                        "Month values must be between 1 and 12", -1);
            }
        } else if (type == DAY_OF_WEEK) {
            if ((val == 0 || val > 7 || end > 7) && (val != ALL_SPEC_INT)
                    && (val != NO_SPEC_INT)) {
                throw new ParseException(
                        "Day-of-Week values must be between 1 and 7", -1);

View on GitHub (pinned to 96fb33f5ec)

Solutions

  1. Ensure all hour values are integers from 0 to 23 (0 = midnight, 23 = 11 PM).
  2. For midnight use 0, not 24 or 12.
  3. Validate dynamically generated hour values against the 0–23 range.

Example fix

// before
String cron = "0 0 24 * * ?";  // 24 is invalid
// after
String cron = "0 0 0 * * ?";  // midnight (hour 0)
Defensive patterns

Strategy: validation

Validate before calling

// Validate hour field values are 0-23
String hourField = fields[2];
for (String token : hourField.split(",")) {
    if (token.equals("*") || token.equals("?")) continue;
    String base = token.split("[/\\-]")[0];
    int val = Integer.parseInt(base);
    if (val < 0 || val > 23) throw new IllegalArgumentException("Hour must be 0-23: " + val);
}

Type guard

boolean isValidHour(String field) {
    for (String token : field.split(",")) {
        if (token.equals("*") || token.equals("?")) continue;
        try {
            for (String part : token.split("[/\\-]")) {
                int val = Integer.parseInt(part);
                if (val < 0 || val > 23) return false;
            }
        } catch (NumberFormatException e) { return false; }
    }
    return true;
}

Try / catch

try {
    CronExpression cron = new CronExpression(expr);
} catch (ParseException e) {
    if (e.getMessage().contains("Hour values must be between 0 and 23")) {
        // fix the hour field value
    }
    throw e;
}

Prevention

When it happens

Trigger: 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'.

Common situations: 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.

Related errors


AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14). Data as JSON: /api/errors/ae336372d7f5c757. Report an issue: GitHub.