pola-rs/polars · error
invalid or out-of-range datetime
Error message
invalid or out-of-range datetime
What it means
`date32_to_datetime` converts an i32 `date32` (days since Unix epoch) to a `NaiveDateTime`. The conversion goes through the fallible `date32_to_datetime_opt`, which returns `None` when the day count (via `TimeDelta::try_days`) or the resulting date is out of chrono's representable range. The infallible wrapper `.expect("invalid or out-of-range datetime")` panics in that case.
Solutions
- Call the fallible `date32_to_datetime_opt(v)` instead and handle the `None` case.
- Validate `v` is a plausible day offset before conversion (e.g. within a sane year range around the epoch).
- Sanitize/replace sentinel values (i32::MAX/MIN, u32-cast garbage) in the source column before conversion.
Example fix
// before
let dt = date32_to_datetime(v); // panics on i32::MAX
// after
match date32_to_datetime_opt(v) {
Some(dt) => dt,
None => return Err(format!("date32 value {v} out of representable range")),
} Defensive patterns
Strategy: validation
Validate before calling
fn date32_in_range(v: i32) -> bool {
(-100_000..100_000).contains(&v) // days within ±~274 years of epoch
} Try / catch
// Prefer the fallible variant over catching the panic:
match date32_to_datetime_opt(v) {
Some(dt) => /* use dt */,
None => /* handle out-of-range */,
} Prevention
- Use the `_opt` variants in application code
- Filter sentinel values (i32::MAX/MIN) from date32 columns before conversion
- Confirm units: date32 is days since 1970-01-01
When it happens
Trigger: Calling `date32_to_datetime(v)` with a `v` so large or negative that `TimeDelta::try_days` fails or the resulting timestamp overflows chrono's `NaiveDateTime` range (roughly ±262,000 years).
Common situations: Corrupt or sentinel i32 values (e.g. i32::MAX) in a date32 column; unit confusion (passing seconds/milliseconds instead of days); extreme synthetic test data.
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
- out-of-range date
- out-of-range duration
- out-of-range in duration conversion
- invalid time
- not implemented
AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18).
Data as JSON: /api/errors/040bb505d15f0329.
Report an issue: GitHub.
Appendix: source
Thrown at crates/polars-arrow/src/temporal_conversions.rs:34
pub const NANOSECONDS: i64 = 1_000_000_000;
/// Number of milliseconds in a day
pub const MILLISECONDS_IN_DAY: i64 = SECONDS_IN_DAY * MILLISECONDS;
/// Number of microseconds in a day
pub const MICROSECONDS_IN_DAY: i64 = SECONDS_IN_DAY * MICROSECONDS;
/// Number of nanoseconds in a day
pub const NANOSECONDS_IN_DAY: i64 = SECONDS_IN_DAY * NANOSECONDS;
/// Number of days between 0001-01-01 and 1970-01-01
pub const EPOCH_DAYS_FROM_CE: i32 = 719_163;
#[inline]
fn unix_epoch() -> NaiveDateTime {
DateTime::UNIX_EPOCH.naive_utc()
}
/// 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> {View on GitHub (pinned to fe841f959e)