pola-rs/polars · error
out-of-range date
Error message
out-of-range date
What it means
Panics inside date32_to_date when NaiveDate::from_num_days_from_ce_opt(EPOCH_DAYS_FROM_CE + days) returns None, i.e. the i32 day count falls outside chrono NaiveDate's representable span (about years -262144..262143). The infallible wrapper uses .expect('out-of-range date') so out-of-range physical values abort rather than yield null.
Source
Thrown at crates/polars-arrow/src/temporal_conversions.rs:47
}
/// converts a `i32` representing a `date32` to [`NaiveDateTime`]
#[inline]
pub fn date32_to_datetime(v: i32) -> NaiveDateTime {
date32_to_datetime_opt(v).expect("invalid or out-of-range datetime")
}
/// converts a `i32` representing a `date32` to [`NaiveDateTime`]
#[inline]
pub fn date32_to_datetime_opt(v: i32) -> Option<NaiveDateTime> {
let delta = TimeDelta::try_days(v.into())?;
unix_epoch().checked_add_signed(delta)
}
/// converts a `i32` representing a `date32` to [`NaiveDate`]
#[inline]
pub fn date32_to_date(days: i32) -> NaiveDate {
date32_to_date_opt(days).expect("out-of-range date")
}
/// converts a `i32` representing a `date32` to [`NaiveDate`]
#[inline]
pub fn date32_to_date_opt(days: i32) -> Option<NaiveDate> {
NaiveDate::from_num_days_from_ce_opt(EPOCH_DAYS_FROM_CE + days)
}
/// 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]View on GitHub (pinned to df599052da)
Solutions
- Use date32_to_date_opt(days) and handle None (null/skip)
- Validate day counts against chrono's range before conversion
- Fix the upstream unit mismatch that put non-day values in the column
- Use Polars-level casts with strict=False so bad values become null
Example fix
// before let d = date32_to_date(days); // panics for out-of-range days // after let d = date32_to_date_opt(days); // Option<NaiveDate> let d = d.unwrap_or_default(); // or propagate as null
Defensive patterns
Strategy: validation
Validate before calling
use polars_arrow::temporal_conversions::date32_to_date_opt;
if date32_to_date_opt(days).is_none() {
// treat as null / corrupt value
} Type guard
fn date32_in_chrono_range(days: i32) -> bool {
polars_arrow::temporal_conversions::date32_to_date_opt(days).is_some()
} Prevention
- Use date32_to_date_opt instead of the panicking wrapper on untrusted data
- Scan Date columns for i32 extremes before calendar formatting
- Pin down units in schemas at write time to avoid ms-in-days drift
- Let invalid values become null via non-strict casts where semantics allow
When it happens
Trigger: Converting a Date array to calendar dates when it holds sentinel or corrupt values (i32::MIN, i32::MAX) - common when a millisecond-epoch column was misdeclared as date32.
Common situations: Schema drift between writer and reader; corrupt parquet/IPC sources; uninitialized buffers read as dates; fuzzed inputs.
Related errors
- invalid or out-of-range datetime
- invalid time
- 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/b1280f24e456c281.
Report an issue: GitHub.