{"record":{"id":"7ce0f7ffa9d86295","repo":"pola-rs/polars","slug":"comparing-datetimes-with-different-units-or-timezo","errorCode":null,"errorMessage":"comparing datetimes with different units or timezones is not supported","messagePattern":"comparing datetimes with different units or timezones is not supported","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-core/src/datatypes/any_value.rs","lineNumber":1427,"sourceCode":"            (UInt32(l), UInt32(r)) => l.partial_cmp(r),\n            (UInt64(l), UInt64(r)) => l.partial_cmp(r),\n            (UInt128(l), UInt128(r)) => l.partial_cmp(r),\n            (Int8(l), Int8(r)) => l.partial_cmp(r),\n            (Int16(l), Int16(r)) => l.partial_cmp(r),\n            (Int32(l), Int32(r)) => l.partial_cmp(r),\n            (Int64(l), Int64(r)) => l.partial_cmp(r),\n            (Int128(l), Int128(r)) => l.partial_cmp(r),\n            (Float16(l), Float16(r)) => Some(l.tot_cmp(r)),\n            (Float32(l), Float32(r)) => Some(l.tot_cmp(r)),\n            (Float64(l), Float64(r)) => Some(l.tot_cmp(r)),\n            (String(l), String(r)) => l.partial_cmp(r),\n            (Binary(l), Binary(r)) => l.partial_cmp(r),\n            #[cfg(feature = \"dtype-date\")]\n            (Date(l), Date(r)) => l.partial_cmp(r),\n            #[cfg(feature = \"dtype-datetime\")]\n            (Datetime(lt, lu, lz), Datetime(rt, ru, rz)) => {\n                if lu != ru || lz != rz {\n                    unimplemented!(\n                        \"comparing datetimes with different units or timezones is not supported\"\n                    );\n                }\n\n                lt.partial_cmp(rt)\n            },\n            #[cfg(feature = \"dtype-duration\")]\n            (Duration(lt, lu), Duration(rt, ru)) => {\n                if lu != ru {\n                    unimplemented!(\"comparing durations with different units is not supported\");\n                }\n\n                lt.partial_cmp(rt)\n            },\n            #[cfg(feature = \"dtype-time\")]\n            (Time(l), Time(r)) => l.partial_cmp(r),\n            #[cfg(feature = \"dtype-categorical\")]\n            (Categorical(l_cat, l_map), Categorical(r_cat, r_map)) => unsafe {","sourceCodeStart":1409,"sourceCodeEnd":1445,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/crates/polars-core/src/datatypes/any_value.rs#L1409-L1445","documentation":"AnyValue::partial_cmp only supports comparing two Datetime values when they have identical TimeUnit and TimeZone. Comparing e.g. a millisecond datetime with a nanosecond one, or a UTC datetime with a zoned one, is rejected with unimplemented!() because raw integer comparison across units/zones would be wrong.","triggerScenarios":"Calling AnyValue::partial_cmp on two AnyValue::Datetime values where the TimeUnit (lu != ru) or the TimeZone string (lz != rz) differs — typically by extracting values from two datetime columns with different time units or timezone settings and comparing them directly.","commonSituations":"Comparing a ms-precision column with a us/ns-precision column, comparing tz-aware vs naive datetimes, or mixing datetimes parsed with different `.str.to_datetime(time_unit=..., time_zone=...)` settings in filters/sorts over extracted AnyValues.","solutions":["Cast both datetime columns to the same time unit (e.g. TimeUnit::Microseconds) and the same time zone before comparing","Use polars expressions (col comparison operators) instead of raw AnyValue comparison; they handle unit conversion","Convert one side with `.dt.convert_time_zone(...)` / `.dt.cast_time_unit(...)` before the comparison","Normalize parsing: always specify explicit time_unit and time_zone in to_datetime so columns match"],"exampleFix":"// before: comparing values from columns with different units\nlet a = df.column(\"ts_ms\")?.as_materialized_series(); // Datetime(ms, UTC)\nlet b = df.column(\"ts_us\")?.as_materialized_series(); // Datetime(us, UTC)\n// comparing AnyValues from a and b panics\n// after: unify unit and timezone first\nlet b = b.cast(&DataType::Datetime(TimeUnit::Milliseconds, Some(PlSmallStr::from_static(\"UTC\"))))?;\nlet eq = a.equal(&b)?;","handlingStrategy":"validation","validationCode":"fn datetimes_comparable(a: &AnyValue, b: &AnyValue) -> bool {\n    match (a, b) {\n        (AnyValue::Datetime(_, lu, lz), AnyValue::Datetime(_, ru, rz)) => lu == ru && lz == rz,\n        _ => false,\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Standardize time_unit and time_zone at parse time (explicit to_datetime args)","Cast to a common unit/timezone before extracting AnyValues","Use expression-level datetime comparisons which normalize units","Never mix tz-aware and naive datetime columns without conversion"],"tags":["polars","datetime","timezone","comparison"],"backgroundTag":"dtype-mismatch","analyzedSha":"fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e","analyzedAt":"2026-09-18T22:14:11.667Z","contentChangedAt":"2026-09-18T22:14:11.667Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}