{"record":{"id":"9ef17acd3948afeb","repo":"pandas-dev/pandas","slug":"already-tz-aware-use-tz-convert-to-convert","errorCode":null,"errorMessage":"Already tz-aware, use tz_convert to convert.","messagePattern":"Already tz-aware, use tz_convert to convert\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/datetimes.py","lineNumber":1113,"sourceCode":"        0   2015-03-29 03:30:00+02:00\n        1   2015-03-29 03:30:00+02:00\n        dtype: datetime64[ns, Europe/Warsaw]\n        \"\"\"  # noqa: E501\n        nonexistent_options = (\"raise\", \"NaT\", \"shift_forward\", \"shift_backward\")\n        if nonexistent not in nonexistent_options and not isinstance(\n            nonexistent, timedelta\n        ):\n            raise ValueError(\n                \"The nonexistent argument must be one of 'raise', \"\n                \"'NaT', 'shift_forward', 'shift_backward' or \"\n                \"a timedelta object\"\n            )\n\n        if self.tz is not None:\n            if tz is None:\n                new_dates = tz_convert_from_utc(self.asi8, self.tz, reso=self._creso)\n            else:\n                raise TypeError(\"Already tz-aware, use tz_convert to convert.\")\n        else:\n            tz = timezones.maybe_get_tz(tz)\n            # Convert to UTC\n\n            new_dates = tzconversion.tz_localize_to_utc(\n                self.asi8,\n                tz,\n                ambiguous=ambiguous,\n                nonexistent=nonexistent,\n                creso=self._creso,\n            )\n        new_dates_dt64 = new_dates.view(f\"M8[{self.unit}]\")\n        dtype = tz_to_dtype(tz, unit=self.unit)\n\n        return self._simple_new(new_dates_dt64, dtype=dtype)\n\n    # ----------------------------------------------------------------\n    # Conversion Methods - Vectorized analogues of Timestamp methods","sourceCodeStart":1095,"sourceCodeEnd":1131,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/datetimes.py#L1095-L1131","documentation":"Raised by DatetimeArray.tz_localize when the data is already tz-aware (`self.tz is not None`) and a non-None target tz is supplied. tz_localize attaches a tz to tz-naive data; once data is aware, switching tz is tz_convert's job. The check happens after the nonexistent-options validation.","triggerScenarios":"Calling `aware_dti.tz_localize('US/Eastern')` on data that already has a tz (e.g. data loaded from a database with a tz, or previously localized). Also `aware_series.dt.tz_localize('UTC')`.","commonSituations":"Re-running a notebook cell that performed tz_localize — the second run hits already-aware data. Composing pipelines that localize defensively without first checking awareness. Loading Parquet/SQL that preserves tz and then unconditionally localizing.","solutions":["Use tz_convert to change tz: `aware_obj.dt.tz_convert('US/Eastern')`.","If you want to drop and re-attach a different tz: `aware_obj.dt.tz_localize(None).dt.tz_localize(new_tz)`.","Guard with awareness check: `if s.dt.tz is None: s = s.dt.tz_localize(tz)`.","To drop tz entirely: `aware_obj.dt.tz_localize(None)`."],"exampleFix":"// before\ns.dt.tz_localize('US/Eastern')  # s is already tz-aware\n\n// after\ns.dt.tz_convert('US/Eastern')","handlingStrategy":"validation","validationCode":"import pandas as pd\n\ndef safe_localize(obj, tz):\n    if obj.dt.tz is None:\n        return obj.dt.tz_localize(tz)\n    return obj.dt.tz_convert(tz)","typeGuard":"def is_tz_aware(obj) -> bool:\n    return getattr(getattr(obj, 'dtype', None), 'tz', None) is not None","tryCatchPattern":"try:\n    out = s.dt.tz_localize(tz)\nexcept TypeError as e:\n    if 'Already tz-aware' in str(e):\n        out = s.dt.tz_convert(tz)\n    else:\n        raise","preventionTips":["Make notebooks idempotent: check awareness before localizing.","Centralize tz policy so data is localized exactly once at ingest."],"tags":["datetime","timezone","tz-localize","tz-convert"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}