{"record":{"id":"913b6bed746dcdf7","repo":"pandas-dev/pandas","slug":"as-unit-not-implemented-for-pa-type","errorCode":null,"errorMessage":"as_unit not implemented for {pa_type}","messagePattern":"as_unit not implemented for (.+?)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/arrow/array.py","lineNumber":3932,"sourceCode":"        data = self._pa_array.to_pylist()\n        if self._dtype.pyarrow_dtype.unit == \"ns\":\n            data = [None if ts is None else ts.to_pytimedelta() for ts in data]\n        return np.array(data, dtype=object)\n\n    def _dt_total_seconds(self) -> Self:\n        unit = self._pa_array.type.unit\n        unit_per_second = {\"s\": 1.0, \"ms\": 1e3, \"us\": 1e6, \"ns\": 1e9}\n        result = pc.divide(pc.cast(self._pa_array, pa.int64()), unit_per_second[unit])\n        return self._from_pyarrow_array(result)\n\n    def _dt_as_unit(self, unit: str) -> Self:\n        pa_type = self._pa_array.type\n        if pa.types.is_timestamp(pa_type):\n            target_type = pa.timestamp(unit, tz=pa_type.tz)\n        elif pa.types.is_duration(pa_type):\n            target_type = pa.duration(unit)\n        else:\n            raise NotImplementedError(f\"as_unit not implemented for {pa_type}\")\n\n        nanos_per_unit = {\"s\": 1_000_000_000, \"ms\": 1_000_000, \"us\": 1_000, \"ns\": 1}\n        from_nanos = nanos_per_unit[pa_type.unit]\n        to_nanos = nanos_per_unit[unit]\n        if to_nanos <= from_nanos:\n            # Same or finer resolution: exact upscale. Use safe=True so that\n            # out-of-bounds values raise instead of silently wrapping, matching\n            # numpy/pandas as_unit.\n            try:\n                result = pc.cast(self._pa_array, target_type)\n            except pa.ArrowInvalid as err:\n                err_type = (\n                    OutOfBoundsDatetime\n                    if pa.types.is_timestamp(pa_type)\n                    else OutOfBoundsTimedelta\n                )\n                raise err_type(\n                    f\"Cannot convert {pa_type} to {target_type} without overflow\"","sourceCodeStart":3914,"sourceCodeEnd":3950,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/arrow/array.py#L3914-L3950","documentation":"Raised by ArrowExtensionArray._dt_as_unit when the array's pyarrow type is neither a timestamp nor a duration. _dt_as_unit only knows how to rescale those two type families; any other type (date32/date64, int, string, etc.) hits the else branch with NotImplementedError. Reached through Series.dt.as_unit() on a pyarrow-backed datetime/timedelta-like Series.","triggerScenarios":"Calling `s.dt.as_unit(\"ms\")` on a Series whose dtype is `date32[pyarrow]`, `date64[pyarrow]`, or a non-temporal pyarrow type that happens to expose a `.dt` accessor (rare). Date types have no sub-day resolution to convert.","commonSituations":"Treating a date column as if it had a time unit; loading Arrow data where dates (not timestamps) were stored; trying to normalize units on a column before arithmetic that actually needs a timestamp.","solutions":["Convert dates to timestamps first: `s.astype(\"timestamp[us][pyarrow]\").dt.as_unit(\"ms\")`.","If the column should be a duration, cast to a duration type before as_unit.","Verify the dtype with `s.dtype` and ensure it is timestamp[pyarrow] or duration[pyarrow] before calling as_unit.","Use `.astype(\"datetime64[ns]\")` then `.dt.as_unit(...)` if you want the numpy-backed path."],"exampleFix":"# before\ns = pd.Series(pd.to_datetime([\"2024-01-01\"]).date, dtype=\"date32[pyarrow]\")\ns.dt.as_unit(\"ms\")  # NotImplementedError\n\n# after\ns.astype(\"timestamp[us][pyarrow]\").dt.as_unit(\"ms\")","handlingStrategy":"validation","validationCode":"import pyarrow as pa\n\ndef can_as_unit(s) -> bool:\n    pa_dt = getattr(s.dtype, \"pyarrow_dtype\", None)\n    return pa_dt is not None and (pa.types.is_timestamp(pa_dt) or pa.types.is_duration(pa_dt))\n\ndef safe_as_unit(s, unit):\n    if not can_as_unit(s):\n        raise NotImplementedError(f\"dt.as_unit needs timestamp/duration pyarrow dtype, got {s.dtype}\")\n    return s.dt.as_unit(unit)","typeGuard":"import pyarrow as pa\n\ndef is_temporal_rescalable(s) -> bool:\n    pa_dt = getattr(s.dtype, \"pyarrow_dtype\", None)\n    return pa_dt is not None and (pa.types.is_timestamp(pa_dt) or pa.types.is_duration(pa_dt))","tryCatchPattern":"try:\n    out = s.dt.as_unit(unit)\nexcept NotImplementedError:\n    out = s.astype(\"timestamp[us][pyarrow]\").dt.as_unit(unit)","preventionTips":["Convert date types to timestamp[pyarrow] before as_unit.","Document the supported dtype set for as_unit in shared temporal utilities.","Validate dtype before rescaling in pipelines."],"tags":["pyarrow","datetime-accessor","not-implemented"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}