pola-rs/polars · error
invalid time
Error message
invalid time
What it means
Panics inside time32s_to_time: the i32 seconds value is cast with 'v as u32', so any negative value wraps to a huge u32, and NaiveTime::from_num_seconds_from_midnight_opt requires seconds < 86400. Any v < 0 or v >= 86400 therefore fails the .expect('invalid time').
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 df599052da)
Solutions
- Range-check first: accept only 0 <= v < 86_400
- Null out or clamp invalid values before conversion
- Fix the unit mismatch upstream (ms vs s)
- Where possible use the Polars cast layer with strict=False to emit nulls
Example fix
// before
let t = time32s_to_time(v); // panics for v < 0 or v >= 86_400
// after
let t = (0..86_400).contains(&v)
.then(|| time32s_to_time(v))
.unwrap_or(NaiveTime::MIN); // or propagate null Defensive patterns
Strategy: validation
Validate before calling
fn time32s_valid(v: i32) -> bool {
(0..86_400).contains(&v) // seconds within one day
} Type guard
fn is_valid_time32s(v: i32) -> bool {
(0..86_400).contains(&v)
} Prevention
- Remember time32(s) must be 0..=86399; negatives wrap when cast to u32 and panic
- Reject or null -1 sentinels in time-of-day columns before conversion
- Verify seconds vs milliseconds units with the producer
- Filter invalid values at load time rather than deep in display logic
When it happens
Trigger: Converting a time32(s) array containing negative values (sentinels, misparsed data) or values >= 86400 (overflow from unit mismatch, e.g. milliseconds stored in a seconds column).
Common situations: CSVs with '-1' defaults in time columns; ms-epoch-of-day values written into a time32(s) field; corrupt arrow data.
Related errors
- invalid or out-of-range datetime
- out-of-range date
- out-of-range duration
- out-of-range in duration conversion
- not implemented
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/830c91ce85a03a93.
Report an issue: GitHub.