{"record":{"id":"d760087ddc054a9f","repo":"pandas-dev/pandas","slug":"cannot-convert-tz-naive-timestamps-use-tz-localiz-d76008","errorCode":null,"errorMessage":"Cannot convert tz-naive timestamps, use tz_localize to localize","messagePattern":"Cannot convert tz-naive timestamps, use tz_localize to localize","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/datetimes.py","lineNumber":944,"sourceCode":"        ... )\n\n        >>> dti\n        DatetimeIndex(['2014-08-01 09:00:00+02:00',\n                       '2014-08-01 10:00:00+02:00',\n                       '2014-08-01 11:00:00+02:00'],\n                        dtype='datetime64[us, Europe/Berlin]', freq='h')\n\n        >>> dti.tz_convert(None)\n        DatetimeIndex(['2014-08-01 07:00:00',\n                       '2014-08-01 08:00:00',\n                       '2014-08-01 09:00:00'],\n                        dtype='datetime64[us]', freq='h')\n        \"\"\"  # noqa: E501\n        tz = timezones.maybe_get_tz(tz)\n\n        if self.tz is None:\n            # tz naive, use tz_localize\n            raise TypeError(\n                \"Cannot convert tz-naive timestamps, use tz_localize to localize\"\n            )\n\n        # No conversion since timestamps are all UTC to begin with\n        dtype = tz_to_dtype(tz, unit=self.unit)\n        return self._simple_new(self._ndarray, dtype=dtype)\n\n    @dtl.ravel_compat\n    def tz_localize(\n        self,\n        tz,\n        ambiguous: TimeAmbiguous = \"raise\",\n        nonexistent: TimeNonexistent = \"raise\",\n    ) -> Self:\n        \"\"\"\n        Localize tz-naive Datetime Array/Index to tz-aware Datetime Array/Index.\n\n        This method takes a time zone (tz) naive Datetime Array/Index object","sourceCodeStart":926,"sourceCodeEnd":962,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/datetimes.py#L926-L962","documentation":"Raised by DatetimeArray.tz_convert when self.tz is None. tz_convert is for changing from one tz to another and presupposes that the wall times are anchored to UTC; for tz-naive data that anchor does not exist, so you must first attach one via tz_localize. The docstring example shows the expected tz-aware usage.","triggerScenarios":"Calling `naive_dti.tz_convert('US/Eastern')`, `naive_series.dt.tz_convert('UTC')`, or any tz_convert on data whose `.dt.tz` is None. Common when reading CSV (which yields naive datetime64) and immediately trying to convert to a business tz.","commonSituations":"Loading a CSV with `pd.read_csv(parse_dates=[...])` yields tz-naive data; calling tz_convert instead of tz_localize. Assuming to_datetime gives UTC-anchored data (it does not — it gives naive wall times).","solutions":["Use tz_localize first to attach the source tz, then tz_convert: `s.dt.tz_localize('UTC').dt.tz_convert('US/Eastern')`.","If you know the source wall time was already UTC: `s.dt.tz_localize('UTC')` (and stop if that is the desired output).","Check awareness before calling: `if s.dt.tz is None: s = s.dt.tz_localize('UTC')`."],"exampleFix":"// before\ns = pd.to_datetime(df['ts']).dt.tz_convert('US/Eastern')\n\n// after\ns = pd.to_datetime(df['ts']).dt.tz_localize('UTC').dt.tz_convert('US/Eastern')","handlingStrategy":"validation","validationCode":"import pandas as pd\n\ndef convert_tz(series, target):\n    if series.dt.tz is None:\n        series = series.dt.tz_localize('UTC')\n    return series.dt.tz_convert(target)","typeGuard":"def is_tz_aware_series(s) -> bool:\n    return getattr(getattr(s, 'dtype', None), 'tz', None) is not None","tryCatchPattern":"try:\n    out = s.dt.tz_convert(target)\nexcept TypeError as e:\n    if 'tz-naive' in str(e):\n        out = s.dt.tz_localize('UTC').dt.tz_convert(target)\n    else:\n        raise","preventionTips":["Wrap tz conversion in a single helper that localizes-then-converts.","After read_csv, immediately decide and apply a tz policy."],"tags":["datetime","timezone","tz-convert","tz-localize"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}