{"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":1410,"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":1392,"sourceCodeEnd":1428,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/crates/polars-core/src/datatypes/any_value.rs#L1392-L1428","documentation":"AnyValue::partial_cmp panics when ordering two Datetime scalars whose time units (us/ms/ns) or time zones differ. The raw i64 counts are only comparable after unit/timezone alignment, which the scalar comparison deliberately does not perform.","triggerScenarios":"Ordering comparisons (<, >, min/max, sort keys) between datetime AnyValues from columns with different dtypes, e.g. Datetime('ms') vs Datetime('us'), or a tz-aware Datetime('us', 'UTC') against a naive Datetime('us').","commonSituations":"Merging frames where one writer produced millisecond and another microsecond timestamps, comparing tz-aware against naive datetimes, or generic scalar-min/max utilities over mixed datetime columns.","solutions":["Align time units before comparing: col.dt.cast_time_unit('us') (or convert_time_unit in expressions)","Align time zones: use dt.convert_time_zone(...) / dt.replace_time_zone(...) so both sides have the same tz (including both naive)","Cast both columns to a single canonical Datetime dtype (e.g. .cast(pl.Datetime('us', 'UTC'))) before extracting scalars"],"exampleFix":"# before\nav_cmp = df1[\"ts\"].get(0) < df2[\"ts\"].get(0)  # ms vs us -> panic\n\n# after\nts1 = df1[\"ts\"].dt.cast_time_unit(\"us\").get(0)\nts2 = df2[\"ts\"].dt.cast_time_unit(\"us\").get(0)\nav_cmp = ts1 < ts2","handlingStrategy":"validation","validationCode":"def datetimes_comparable(a: pl.Series, b: pl.Series) -> bool:\n    da, db = a.dtype, b.dtype\n    return (\n        isinstance(da, pl.Datetime) and isinstance(db, pl.Datetime)\n        and da.time_unit == db.time_unit\n        and da.time_zone == db.time_zone\n    )","typeGuard":"def aligned_datetime(s: pl.Series, unit: str = \"us\", tz=None) -> pl.Series:\n    s = s.dt.cast_time_unit(unit)\n    if tz is not None:\n        s = s.dt.convert_time_zone(tz)\n    elif s.dtype.time_zone is not None:\n        s = s.dt.replace_time_zone(None)\n    return s","tryCatchPattern":null,"preventionTips":["Standardize all datetime columns to one unit and tz policy at load time","Check dtype.time_unit and dtype.time_zone before scalar comparisons"],"tags":["rust","polars","panic","unimplemented","any-value","datetime","time-unit","timezone","ordering"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}