OpenRefine/OpenRefine · error · CalendarParserException

Bad hour

Error message

Bad hour <val>

What it means

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.

Solutions

  1. Convert 24:xx times to 00:xx in the source data
  2. Ensure AM/PM markers are present and correct for 12-hour times so the parser can normalize
  3. Pre-validate hour range (0-23) before invoking the parser
  4. Catch CalendarParserException and treat the cell as an invalid date

Example fix

// before
String t = "24:15"; // Bad hour 24
// after
String t = "00:15"; // midnight in 24-hour notation
Defensive patterns

Strategy: validation

Validate before calling

if (hour < 0 || hour > 23) throw new IllegalArgumentException("hour out of range: " + hour);

Try / catch

try {
    parser.setHour(hour);
} catch (CalendarParserException e) {
    log.error("Invalid hour token: {}", e.getMessage());
}

Prevention

When it happens

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

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

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of OpenRefine/OpenRefine@a946177e04 (2026-09-08). Data as JSON: /api/errors/f1e42fca90bfd77e. Report an issue: GitHub.

Appendix: source

Thrown at modules/core/src/main/java/com/google/refine/expr/util/CalendarParser.java:380

     * Set the hour value.
     * 
     * @param val
     *            hour value
     * 
     * @throws CalendarParserException
     *             if the value is not a valid hour
     */
    void setHour(int val) throws CalendarParserException {
        final int tmpHour;
        if (timePostMeridian) {
            tmpHour = val + 12;
            timePostMeridian = false;
        } else {
            tmpHour = val;
        }

        if (tmpHour < 0 || tmpHour > 23) {
            throw new CalendarParserException("Bad hour " + val);
        }

        hour = tmpHour;
    }

    /**
     * Set the millisecond value.
     * 
     * @param val
     *            millisecond value
     * 
     * @throws CalendarParserException
     *             if the value is not a valid millisecond
     */
    void setMillisecond(int val) throws CalendarParserException {
        if (val < 0 || val > 999) {
            throw new CalendarParserException("Bad millisecond " + val);
        }

View on GitHub (pinned to a946177e04)