{"record":{"id":"9fb10f4194706d30","repo":"pola-rs/polars","slug":"cannot-compare-datetime-datetime-to-series-of-type","errorCode":null,"errorMessage":"cannot compare datetime.datetime to Series of type {self.dtype}","messagePattern":"cannot compare datetime\\.datetime to Series of type (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/series/series.py","lineNumber":764,"sourceCode":"            f = get_ffi_func(op + \"_<>\", Float64, self._s)\n            assert f is not None\n            return self._from_pyseries(f(other))\n\n        elif isinstance(other, datetime):\n            if self.dtype == Date:\n                # require upcast when comparing date series to datetime\n                self = self.cast(Datetime(\"us\"))\n                time_unit = \"us\"\n            elif self.dtype == Datetime:\n                # Use local time zone info\n                time_zone = self.dtype.time_zone  # type: ignore[attr-defined]\n                if str(other.tzinfo) != str(time_zone):\n                    msg = f\"datetime time zone {other.tzinfo!r} does not match Series timezone {time_zone!r}\"\n                    raise TypeError(msg)\n                time_unit = self.dtype.time_unit  # type: ignore[attr-defined]\n            else:\n                msg = f\"cannot compare datetime.datetime to Series of type {self.dtype}\"\n                raise ValueError(msg)\n            ts = datetime_to_int(other, time_unit)  # type: ignore[arg-type]\n            f = get_ffi_func(op + \"_<>\", Int64, self._s)\n            assert f is not None\n            return self._from_pyseries(f(ts))\n\n        elif isinstance(other, time) and self.dtype == Time:\n            d = time_to_int(other)\n            f = get_ffi_func(op + \"_<>\", Int64, self._s)\n            assert f is not None\n            return self._from_pyseries(f(d))\n\n        elif isinstance(other, timedelta) and self.dtype == Duration:\n            time_unit = self.dtype.time_unit  # type: ignore[attr-defined]\n            td = timedelta_to_int(other, time_unit)\n            f = get_ffi_func(op + \"_<>\", Int64, self._s)\n            assert f is not None\n            return self._from_pyseries(f(td))\n","sourceCodeStart":746,"sourceCodeEnd":782,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/py-polars/src/polars/series/series.py#L746-L782","documentation":"In _comp, when the other operand is a datetime.datetime, Polars only supports comparing it against a Series whose dtype is Datetime; for any other dtype (Date, Int64, Utf8, etc.) it raises ValueError. A datetime.datetime is not interchangeable with a date or integer, and Polars refuses the implicit cross-type comparison.","triggerScenarios":"Comparing a Date-typed Series with a datetime.datetime (very common: reading a date column then comparing to datetime.now()); comparing Int64/Utf8 columns holding epoch millis or ISO strings against datetime objects, via ==, !=, <, >, <=, >=.","commonSituations":"datetime.now() returning a datetime while the column was parsed as pl.Date (e.g. from a 'YYYY-MM-DD' CSV column); comparing raw epoch-integer columns against datetimes without casting; forgetting .date() on a datetime before comparing to a Date column.","solutions":["If the Series dtype is Date, compare with a datetime.date instead: datetime.now().date(), or cast the Series: s.cast(pl.Datetime) then compare with the datetime.","If the column holds epoch integers, cast explicitly: s.cast(pl.Datetime('ms')) (or convert the datetime with int(dt.timestamp() * 1000)).","If the column holds strings, parse it first: s.str.to_datetime() then compare.","Prefer pl.lit(...) on the Polars side, which produces clearer dtype-aware comparison behavior than raw Python objects."],"exampleFix":"// before\ns = pl.Series('d', [date(2024, 1, 1)])  # dtype Date\ns > datetime.now()  # ValueError: cannot compare datetime.datetime to Series of type Date\n\n// after\ns > datetime.now().date()  # compare date-to-date\n# or: s.cast(pl.Datetime) > datetime.now()","handlingStrategy":"validation","validationCode":"assert s.dtype in (pl.Date, pl.Datetime), f'unexpected dtype {s.dtype}'\nif s.dtype == pl.Date and isinstance(py_value, datetime):\n    py_value = py_value.date()  # or cast Series: s.cast(pl.Datetime)","typeGuard":"def comparable_py_type(dtype: pl.DataType):\n    import datetime as _dt\n    return _dt.date if dtype == pl.Date else _dt.datetime","tryCatchPattern":"try:\n    result = s > dt\nexcept ValueError as e:\n    if 'cannot compare datetime.datetime' in str(e):\n        result = (s.cast(pl.Datetime) > dt) if s.dtype == pl.Date else (s > dt.date())\n    else:\n        raise","preventionTips":["Match Python types to column dtypes: date for pl.Date, datetime for pl.Datetime.","Use .date() when comparing datetime.now() against Date columns, or cast the column to Datetime.","Prefer pl.lit(...) literals so polars applies dtype-aware coercion and errors.","Parse CSV date columns with explicit dtypes (str.to_datetime / str.to_date) matching the values you will compare against.","Add dtype assertions in tests around comparison logic."],"tags":["python","polars","datetime-comparison","dtype"],"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"}