{"record":{"id":"6e3805f65b7e107c","repo":"pandas-dev/pandas","slug":"cannot-compare-tz-naive-and-tz-aware-datetime-like-6e3805","errorCode":null,"errorMessage":"Cannot compare tz-naive and tz-aware datetime-like objects","messagePattern":"Cannot compare tz-naive and tz-aware datetime-like objects","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/datetimes.py","lineNumber":786,"sourceCode":"\n    def _assert_tzawareness_compat(self, other) -> None:\n        # adapted from _Timestamp._assert_tzawareness_compat\n        other_tz = getattr(other, \"tzinfo\", None)\n        other_dtype = getattr(other, \"dtype\", None)\n\n        if isinstance(other_dtype, DatetimeTZDtype):\n            # Get tzinfo from Series dtype\n            other_tz = other.dtype.tz\n        if other is NaT:\n            # pd.NaT quacks both aware and naive\n            pass\n        elif self.tz is None:\n            if other_tz is not None:\n                raise TypeError(\n                    \"Cannot compare tz-naive and tz-aware datetime-like objects.\"\n                )\n        elif other_tz is None:\n            raise TypeError(\n                \"Cannot compare tz-naive and tz-aware datetime-like objects\"\n            )\n\n    # -----------------------------------------------------------------\n    # Arithmetic Methods\n\n    def _add_offset(self, offset: BaseOffset) -> Self:\n        assert not isinstance(offset, Tick)\n\n        # For pure-timedelta DateOffset with tz-aware data, add to UTC values\n        # directly to avoid nonexistent/ambiguous time errors from\n        # re-localizing wall-time results near DST (GH#28610).\n        if (\n            self.tz is not None\n            and isinstance(offset, RelativeDeltaOffset)\n            and not offset._use_relativedelta\n        ):\n            res_values = self._ndarray + offset._pd_timedelta","sourceCodeStart":768,"sourceCodeEnd":804,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/datetimes.py#L768-L804","documentation":"The mirror case of error 280 from the same _assert_tzawareness_compat method: here self (the DatetimeIndex/array) is tz-aware (self.tz is not None) but the other operand is tz-naive (other_tz is None, and not NaT). Pandas raises because a tz-aware value cannot be meaningfully compared against a wall-time-only value. TypeError.","triggerScenarios":"A tz-aware DatetimeIndex/Series compared with a naive Timestamp, datetime.datetime, or naive index, e.g. aware_dti > pd.Timestamp('2020-01-01'), or filtering an aware Series with a naive scalar. Reached through ==, <, >, merge keys, isin, .between.","commonSituations":"Column localized to UTC for storage, then filtered with naive timestamps from user input; joining an aware index against a naive one produced by pd.date_range without tz; mixing datetime.datetime.now() (naive) with tz-aware data.","solutions":["Localize the naive operand to the aware side's tz, e.g. pd.Timestamp('2020-01-01').tz_localize(aware_dti.tz).","Or tz_convert the aware side to the naive side's implied tz after localizing the naive side.","If wall-time comparison is intended, tz_localize(None) on the aware side (document the trade-off).","Normalize tz across the pipeline at ingestion time so all datetime columns share one awareness."],"exampleFix":"# before\naware_dti > pd.Timestamp('2020-01-01')\n# after\naware_dti > pd.Timestamp('2020-01-01').tz_localize(aware_dti.tz)","handlingStrategy":"validation","validationCode":"def localize_operand(op, target_tz):\n    op_tz = getattr(getattr(op, 'dtype', None), 'tz', None) or getattr(op, 'tzinfo', None)\n    if op_tz is None and target_tz is not None:\n        return op.tz_localize(target_tz) if hasattr(op, 'tz_localize') else pd.Timestamp(op).tz_localize(target_tz)\n    return op","typeGuard":"def is_tz_aware(x) -> bool:\n    dt = getattr(x, 'dtype', None)\n    return getattr(dt, 'tz', None) is not None or getattr(x, 'tzinfo', None) is not None","tryCatchPattern":"try:\n    out = aware_dti > scalar\nexcept TypeError as e:\n    if 'tz-naive and tz-aware' in str(e):\n        scalar = pd.Timestamp(scalar).tz_localize(aware_dti.tz)\n        out = aware_dti > scalar\n    else:\n        raise","preventionTips":["Wrap incoming naive scalars in tz_localize(target) before any comparison.","Keep a single canonical tz for the whole pipeline.","Document which columns are aware in your schema."],"tags":["datetime","timezone","comparison","pandas"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}