pola-rs/polars · error

invalid time

Error message

invalid time

What it means

`time32s_to_time` converts an i32 `time32(s)` value (seconds since midnight) into a `NaiveTime` using `NaiveTime::from_num_seconds_from_midnight_opt`. If the second count is not a valid time-of-day (negative values cast to u32 wrap to huge numbers), the Option is `None` and the wrapper panics with "invalid time".

Solutions

  1. Validate `0 <= v < 86_400` before calling the converter.
  2. Use the fallible `NaiveTime::from_num_seconds_from_midnight_opt(v as u32, 0)` directly and handle `None`.
  3. Clean the column of negative/overflow values before conversion.

Example fix

// before
let t = time32s_to_time(v); // panics for v<0 or v>=86400
// after
if (0..86_400).contains(&v) {
    let t = time32s_to_time(v);
} else {
    return Err(anyhow!("invalid time32 seconds: {v}"));
}
Defensive patterns

Strategy: validation

Validate before calling

fn valid_time32s(v: i32) -> bool {
    (0..86_400).contains(&v)
}

Try / catch

if valid_time32s(v) {
    let t = time32s_to_time(v);
} else {
    // reject or null-out the value
}

Prevention

When it happens

Trigger: Calling `time32s_to_time(v)` with `v < 0` (cast `v as u32` wraps) or `v >= 86400`, producing an invalid seconds-since-midnight value.

Common situations: Negative sentinel values in time32 columns; data written with a different unit (e.g. total seconds of a duration rather than time-of-day); dirty CSV/parquet imports.

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 pola-rs/polars@fe841f959e (2026-09-18). Data as JSON: /api/errors/830c91ce85a03a93. Report an issue: GitHub.

Appendix: source

Thrown at crates/polars-arrow/src/temporal_conversions.rs:73

/// converts a `i64` representing a `date64` to [`NaiveDateTime`]
#[inline]
pub fn date64_to_datetime(v: i64) -> NaiveDateTime {
    TimeDelta::try_milliseconds(v)
        .and_then(|delta| unix_epoch().checked_add_signed(delta))
        .expect("invalid or out-of-range datetime")
}

/// converts a `i64` representing a `date64` to [`NaiveDate`]
#[inline]
pub fn date64_to_date(milliseconds: i64) -> NaiveDate {
    date64_to_datetime(milliseconds).date()
}

/// converts a `i32` representing a `time32(s)` to [`NaiveTime`]
#[inline]
pub fn time32s_to_time(v: i32) -> NaiveTime {
    NaiveTime::from_num_seconds_from_midnight_opt(v as u32, 0).expect("invalid time")
}

/// converts a `i64` representing a `duration(s)` to [`Duration`]
#[inline]
pub fn duration_s_to_duration(v: i64) -> Duration {
    Duration::try_seconds(v).expect("out-of-range duration")
}

/// converts a `i64` representing a `duration(ms)` to [`Duration`]
#[inline]
pub fn duration_ms_to_duration(v: i64) -> Duration {
    Duration::try_milliseconds(v).expect("out-of-range in duration conversion")
}

/// converts a `i64` representing a `duration(us)` to [`Duration`]
#[inline]
pub fn duration_us_to_duration(v: i64) -> Duration {
    Duration::microseconds(v)

View on GitHub (pinned to fe841f959e)