diff --git a/doc/source/whatsnew/v2.0.1.rst b/doc/source/whatsnew/v2.0.1.rst index 9071d242e25b5..bf21d6402d621 100644 --- a/doc/source/whatsnew/v2.0.1.rst +++ b/doc/source/whatsnew/v2.0.1.rst @@ -21,6 +21,7 @@ Fixed regressions Bug fixes ~~~~~~~~~ - Fixed bug in :func:`merge` when merging with ``ArrowDtype`` one one and a NumPy dtype on the other side (:issue:`52406`) +- Bug in :func:`to_datetime` and :func:`to_timedelta` when trying to convert numeric data with a :class:`ArrowDtype` (:issue:`52425`) - Bug in :meth:`Series.describe` not returning :class:`ArrowDtype` with ``pyarrow.float64`` type with numeric data (:issue:`52427`) - Fixed segfault in :meth:`Series.to_numpy` with ``null[pyarrow]`` dtype (:issue:`52443`) diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index 162906200882b..b0ff9cf3fbeea 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -127,6 +127,7 @@ NDArrayBackedExtensionArray, ravel_compat, ) +from pandas.core.arrays.arrow.array import ArrowExtensionArray from pandas.core.arrays.base import ExtensionArray from pandas.core.arrays.integer import IntegerArray import pandas.core.common as com @@ -2209,10 +2210,14 @@ def ensure_arraylike_for_datetimelike(data, copy: bool, cls_name: str): else: data = extract_array(data, extract_numpy=True) - if isinstance(data, IntegerArray): + if isinstance(data, IntegerArray) or ( + isinstance(data, ArrowExtensionArray) and data.dtype.kind in "iu" + ): data = data.to_numpy("int64", na_value=iNaT) copy = False - elif not isinstance(data, (np.ndarray, ExtensionArray)): + elif not isinstance(data, (np.ndarray, ExtensionArray)) or isinstance( + data, ArrowExtensionArray + ): # GH#24539 e.g. xarray, dask object data = np.asarray(data) diff --git a/pandas/tests/tools/test_to_datetime.py b/pandas/tests/tools/test_to_datetime.py index 7d3aaf7fd3744..7b707be97c653 100644 --- a/pandas/tests/tools/test_to_datetime.py +++ b/pandas/tests/tools/test_to_datetime.py @@ -3586,3 +3586,12 @@ def test_ignoring_unknown_tz_deprecated(): with tm.assert_produces_warning(FutureWarning): res = to_datetime([dtstr]) tm.assert_index_equal(res, to_datetime([dtstr[:-5]])) + + +def test_from_numeric_arrow_dtype(any_numeric_ea_dtype): + # GH 52425 + pytest.importorskip("pyarrow") + ser = Series([1, 2], dtype=f"{any_numeric_ea_dtype.lower()}[pyarrow]") + result = to_datetime(ser) + expected = Series([1, 2], dtype="datetime64[ns]") + tm.assert_series_equal(result, expected) diff --git a/pandas/tests/tools/test_to_timedelta.py b/pandas/tests/tools/test_to_timedelta.py index b27a0db4dfe98..b1ab449996685 100644 --- a/pandas/tests/tools/test_to_timedelta.py +++ b/pandas/tests/tools/test_to_timedelta.py @@ -287,3 +287,12 @@ def test_to_timedelta_numeric_ea(self, any_numeric_ea_dtype): result = to_timedelta(ser) expected = Series([pd.Timedelta(1, unit="ns"), pd.NaT]) tm.assert_series_equal(result, expected) + + +def test_from_numeric_arrow_dtype(any_numeric_ea_dtype): + # GH 52425 + pytest.importorskip("pyarrow") + ser = Series([1, 2], dtype=f"{any_numeric_ea_dtype.lower()}[pyarrow]") + result = to_timedelta(ser) + expected = Series([1, 2], dtype="timedelta64[ns]") + tm.assert_series_equal(result, expected)