apache/seatunnel · error · IllegalArgumentException

Time values must use number of milliseconds greater than 0 a

Error message

Time values must use number of milliseconds greater than 0 and less than 86400000000000

What it means

convertLocalTime(Duration) treats a Duration as nanoseconds-of-day and only accepts values in [0, 1 day]. If the Duration is negative or exceeds one day, LocalTime.ofNanoOfDay would be undefined, so the converter throws IllegalArgumentException. Note the message text mentions milliseconds but the check is on nanos via TimeUnit.DAYS.toNanos(1).

Source

Thrown at seatunnel-api/src/main/java/org/apache/seatunnel/api/table/converter/BasicDataConverter.java:717

    default LocalTime convertLocalTime(java.sql.Timestamp value) {
        return LocalTime.of(
                value.getHours(), value.getMinutes(), value.getSeconds(), value.getNanos());
    }

    default LocalTime convertLocalTime(Date value) {
        long millis = (int) (value.getTime() % TimeUnit.SECONDS.toMillis(1));
        int nanosOfSecond = (int) (millis * TimeUnit.MILLISECONDS.toNanos(1));
        return LocalTime.of(
                value.getHours(), value.getMinutes(), value.getSeconds(), nanosOfSecond);
    }

    default LocalTime convertLocalTime(Duration value) {
        Long nanos = value.toNanos();
        if (nanos >= 0 && nanos <= TimeUnit.DAYS.toNanos(1)) {
            return LocalTime.ofNanoOfDay(nanos);
        } else {
            throw new IllegalArgumentException(
                    "Time values must use number of milliseconds greater than 0 and less than 86400000000000");
        }
    }

    default LocalTime convertLocalTime(String value) {
        return LocalTime.parse(value);
    }

    default LocalTime convertLocalTime(Number value) {
        return LocalTime.ofSecondOfDay(value.longValue());
    }

    default LocalDate convertLocalDate(T typeDefine, Object value)
            throws UnsupportedOperationException {
        if (value instanceof LocalDate) {
            return (LocalDate) value;
        }
        if (value instanceof Date) {

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Clamp or modulo the Duration to a single day (duration.minusDays(duration.toDays())) when wrap-around semantics are desired
  2. Fix the source mapping: durations >1 day usually indicate an interval/timestamp field, not a TIME field — map it to TIMESTAMP or a long instead
  3. Guard negative durations at the source and correct upstream data or conversion math

Example fix

// before
Duration d = Duration.ofHours(30); // from MySQL TIME '30:00:00'
LocalTime t = converter.convert(d); // throws
// after
Duration d = Duration.ofHours(30);
LocalTime t = LocalTime.ofNanoOfDay(d.toNanos() % TimeUnit.DAYS.toNanos(1));
Defensive patterns

Strategy: validation

Validate before calling

java.time.Duration d = (java.time.Duration) v;
long nanos = d.toNanos();
if (nanos < 0 || nanos > java.util.concurrent.TimeUnit.DAYS.toNanos(1)) {
    throw new IllegalArgumentException("Duration out of day range: " + d);
}

Type guard

boolean isWithinOneDay(java.time.Duration d) {
    long nanos = d.toNanos();
    return nanos >= 0 && nanos <= java.util.concurrent.TimeUnit.DAYS.toNanos(1);
}

Try / catch

try {
    LocalTime t = converter.convert(duration);
} catch (IllegalArgumentException e) {
    LOG.warn("Duration {} not representable as LocalTime", duration);
    long nanos = duration.toNanos() % java.util.concurrent.TimeUnit.DAYS.toNanos(1);
    LocalTime t = LocalTime.ofNanoOfDay(nanos); // wrap-around fallback
}

Prevention

When it happens

Trigger: Passing a Duration longer than 24 hours (e.g. an interval spanning days) or a negative Duration to convert() for a TIME column.

Common situations: CDC intervals (e.g. Debezium INTERVAL types, MySQL TIME values that can exceed 24h like '850:00:00') mapped to LocalTime; sign errors producing negative durations; misinterpreting the field as an interval when it should be a timestamp.

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 apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/07e628b026a5502c. Report an issue: GitHub.