pola-rs/polars · error
cannot compare datetime.datetime to Series of type {self.dty
Error message
cannot compare datetime.datetime to Series of type {self.dtype} What it means
Raised in Series._comp (py-polars/src/polars/series/series.py:878) when comparing against a datetime.datetime scalar but the Series dtype is neither Date nor Datetime. Polars has special-cased comparison paths for date/datetime/time/timedelta scalars; a datetime falls into that dispatcher, and if the Series holds e.g. Int64, String, or Duration, the combination is meaningless and rejected with ValueError naming the actual dtype.
Source
Thrown at py-polars/src/polars/series/series.py:878
f = get_ffi_func(op + "_<>", Float64, self._s)
assert f is not None
return self._from_pyseries(f(other))
elif isinstance(other, datetime):
if self.dtype == Date:
# require upcast when comparing date series to datetime
self = self.cast(Datetime("us"))
time_unit = "us"
elif self.dtype == Datetime:
# Use local time zone info
time_zone = self.dtype.time_zone # type: ignore[attr-defined]
if str(other.tzinfo) != str(time_zone):
msg = f"datetime time zone {other.tzinfo!r} does not match Series timezone {time_zone!r}"
raise TypeError(msg)
time_unit = self.dtype.time_unit # type: ignore[attr-defined]
else:
msg = f"cannot compare datetime.datetime to Series of type {self.dtype}"
raise ValueError(msg)
ts = datetime_to_int(other, time_unit) # type: ignore[arg-type]
f = get_ffi_func(op + "_<>", Int64, self._s)
assert f is not None
return self._from_pyseries(f(ts))
elif isinstance(other, time) and self.dtype == Time:
d = time_to_int(other)
f = get_ffi_func(op + "_<>", Int64, self._s)
assert f is not None
return self._from_pyseries(f(d))
elif isinstance(other, timedelta) and self.dtype == Duration:
time_unit = self.dtype.time_unit # type: ignore[attr-defined]
td = timedelta_to_int(other, time_unit)
f = get_ffi_func(op + "_<>", Int64, self._s)
assert f is not None
return self._from_pyseries(f(td))
View on GitHub (pinned to df599052da)
Solutions
- Convert the Series to Datetime first: s.cast(pl.Datetime) or s.str.to_datetime() for strings, or pl.from_epoch(s, time_unit="ms") for integers
- If the scalar side is wrong (you meant a date/time/duration), use the matching Python type so the correct branch is taken
- Add schema validation after ingestion so dtype surprises surface before comparison logic
Example fix
# before
s = pl.Series(["2024-01-01", "2024-06-01"]) # strings
s > datetime(2024, 3, 1) # ValueError
# after
s = s.str.to_datetime()
s > datetime(2024, 3, 1)
# for epoch ints: s = pl.from_epoch(s, time_unit="s").cast(pl.Datetime("us")) Defensive patterns
Strategy: validation
Validate before calling
import polars as pl
from datetime import datetime
def comparable_to_datetime(s: pl.Series) -> bool:
return s.dtype in (pl.Date, pl.Datetime) or (isinstance(s.dtype, pl.Datetime))
if not comparable_to_datetime(s):
raise TypeError(f"{s.dtype} Series cannot be compared to datetime; cast first") Type guard
def is_temporal_series(s: pl.Series) -> bool:
return s.dtype.base_type() in (pl.Date, pl.Datetime) Try / catch
try:
mask = s > cutoff
except ValueError as e:
if "cannot compare datetime.datetime" in str(e):
s = s.str.to_datetime() if s.dtype == pl.String else s.cast(pl.Datetime)
mask = s > cutoff
else:
raise Prevention
- Validate dtypes right after ingestion: assert df.schema["ts"] == pl.Datetime("us", "UTC")
- Convert epoch integers with pl.from_epoch and strings with str.to_datetime before comparisons
When it happens
Trigger: pl.Series([1, 2, 3]) < datetime(2024, 1, 1); pl.Series(["a"]).eq(datetime.now()); comparing a Duration or Time Series to a datetime instance.
Common situations: Type drift: a column expected to be Datetime was parsed as String/Int (e.g. CSV ingestion without schema hints, or epoch integers not converted); unit tests comparing the wrong series; mixing up time and datetime objects.
Related errors
- datetime time zone {other.tzinfo!r} does not match Series ti
- Series of type {self.dtype} does not have {op} operator
- cannot do arithmetic with Series of dtype: {self.dtype!r} an
- first cast to integer before dividing datelike dtypes
- first cast to integer before multiplying datelike dtypes
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/9fb10f4194706d30.
Report an issue: GitHub.