diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 83638ce87f7ac..010d4a31b864d 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -651,6 +651,7 @@ Conversion - Bug in :meth:`DataFrame.update` bool dtype being converted to object (:issue:`55509`) - Bug in :meth:`Series.astype` might modify read-only array inplace when casting to a string dtype (:issue:`57212`) - Bug in :meth:`Series.reindex` not maintaining ``float32`` type when a ``reindex`` introduces a missing value (:issue:`45857`) +- Bug in :meth: 'Series.convert_dtype' strips the timezone on an already Timezone aware pyarrow timestamp dtype (:issue:'60237') Strings ^^^^^^^ diff --git a/pandas/core/dtypes/dtypes.py b/pandas/core/dtypes/dtypes.py index 1dd1b12d6ae95..5a88591a144b8 100644 --- a/pandas/core/dtypes/dtypes.py +++ b/pandas/core/dtypes/dtypes.py @@ -2280,7 +2280,8 @@ def numpy_dtype(self) -> np.dtype: # regardless of the pyarrow timestamp units. # This can be removed if/when pyarrow addresses it: # https://github.com/apache/arrow/issues/34462 - return np.dtype(f"datetime64[{self.pyarrow_dtype.unit}]") + if self.pyarrow_dtype.tz is None: + return np.dtype(f"datetime64[{self.pyarrow_dtype.unit}]") if pa.types.is_duration(self.pyarrow_dtype): # pa.duration(unit).to_pandas_dtype() returns ns units # regardless of the pyarrow duration units diff --git a/pandas/tests/extension/test_arrow.py b/pandas/tests/extension/test_arrow.py index c6ac6368f2770..55cec8662a465 100644 --- a/pandas/tests/extension/test_arrow.py +++ b/pandas/tests/extension/test_arrow.py @@ -3505,3 +3505,14 @@ def test_map_numeric_na_action(): result = ser.map(lambda x: 42, na_action="ignore") expected = pd.Series([42.0, 42.0, np.nan], dtype="float64") tm.assert_series_equal(result, expected) + + +def test_convert_dtypes_timezone_series(): + # GH#60237 + ser = pd.Series( + pd.date_range(start="2020-01-01", periods=5, freq="h", tz="UTC"), + dtype="timestamp[ns, tz=UTC][pyarrow]", + ) + expected = ser + result = ser.convert_dtypes(dtype_backend="pyarrow") + tm.assert_series_equal(result, expected)