prestodb/presto · error · IllegalArgumentException

Invalid day-time interval:

Error message

Invalid day-time interval: 

What it means

IntervalDayTime.parseMillis parses a day-time interval string (e.g. '1 12:30:15.000') using the FORMAT regex. If the string does not match the expected '<days> <hours>:<minutes>:<seconds>' shape, this IllegalArgumentException is thrown with the offending value appended to the message.

Source

Thrown at presto-client/src/main/java/com/facebook/presto/client/IntervalDayTime.java:89

        return format("%s%d %02d:%02d:%02d.%03d", sign, day, hour, minute, second, millis);
    }

    public static long parseMillis(String value)
    {
        if (value.equals(LONG_MIN_VALUE)) {
            return Long.MIN_VALUE;
        }

        long signum = 1;
        if (value.startsWith("-")) {
            signum = -1;
            value = value.substring(1);
        }

        Matcher matcher = FORMAT.matcher(value);
        if (!matcher.matches()) {
            throw new IllegalArgumentException("Invalid day-time interval: " + value);
        }

        long days = parseLong(matcher.group(1));
        long hours = parseLong(matcher.group(2));
        long minutes = parseLong(matcher.group(3));
        long seconds = parseLong(matcher.group(4));
        long millis = parseLong(matcher.group(5));

        return toMillis(days, hours, minutes, seconds, millis) * signum;
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Check the input string matches the FORMAT pattern: [sign]days[ ]hours:minutes:seconds[.millis] (e.g. '1 02:03:04.000').
  2. Normalize the value before parsing: trim whitespace, strip trailing 'days'/'day' text, and pad missing components to HH:mm:ss.
  3. Wrap parseMillis in try-catch and surface a user-facing validation message showing the expected format.
  4. Confirm the right parser is used: day-time values must go to IntervalDayTime, year-month values (e.g. '1-6') to IntervalYearMonth.

Example fix

// before
long millis = IntervalDayTime.parseMillis(userInput); // throws on '5 days'
// after
String normalized = userInput.trim().matches(".*(?i)days?") ? userInput.trim().replaceAll("(?i)\\s*days?", "") + " 00:00:00.000" : userInput.trim();
long millis = IntervalDayTime.parseMillis(normalized);
Defensive patterns

Strategy: validation

Validate before calling

private static final Pattern INTERVAL_DAY_TIME = Pattern.compile("-?\\d+\\s*\\d{1,2}:\\d{2}:\\d{2}(\\.\\d{1,3})?");
if (value == null || !INTERVAL_DAY_TIME.matcher(value.trim()).matches()) {
    throw new IllegalArgumentException("Expected day-time interval like '1 02:03:04.000', got: " + value);
}

Try / catch

try { long ms = IntervalDayTime.parseMillis(value); } catch (IllegalArgumentException e) { /* show e.getMessage() with expected format */ }

Prevention

When it happens

Trigger: Calling IntervalDayTime.parseMillis (directly or via INTERVAL literals in the client) with a string that fails the FORMAT regex: wrong field order, missing seconds/milliseconds, extra whitespace, non-numeric fields, or a bare number without the 'd HH:mm:ss' layout.

Common situations: Users typing '5 days' or '36:00:00' instead of '1 12:00:00.000'; passing a year-month style string like '1-6' to a day-time parser; locale-formatted or whitespace-padded values coming from logs or user input.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/ab74907e61c33fcb. Report an issue: GitHub.