{"record":{"id":"3ff5accafbadb952","repo":"pandas-dev/pandas","slug":"dateoffset-other-is-intra-day-and-cannot-be-appl","errorCode":null,"errorMessage":"DateOffset {other} is intra-day and cannot be applied to date32/date64 arrays","messagePattern":"DateOffset (.+?) is intra-day and cannot be applied to date32/date64 arrays","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/arrow/array.py","lineNumber":1289,"sourceCode":"\n        result = np.empty(len(self), dtype=object)\n        result[mask] = self.dtype.na_value\n        result[valid] = op(np.asarray(self, dtype=object)[valid], other)\n\n        if not lib.is_string_array(result, skipna=True):\n            return result\n        return type(self)._from_sequence(result, dtype=self.dtype)\n\n    def _arith_method(self, other, op) -> Self | npt.NDArray[np.object_]:\n        if isinstance(other, BaseOffset) and pa.types.is_date(self._pa_array.type):\n            # Cast date32/date64 → timestamp, apply offset via DatetimeArray, cast back\n            ts_array = type(self)(self._pa_array.cast(pa.timestamp(\"us\")))\n            dt_array = ts_array._to_datetimearray()\n\n            shifted = op(dt_array, other)\n            check = shifted[~shifted.isna()] if shifted._hasna else shifted\n            if not check.is_normalized:\n                raise TypeError(\n                    f\"DateOffset {other} is intra-day and cannot be \"\n                    f\"applied to date32/date64 arrays\"\n                )\n            result_pa = pa.array(shifted._ndarray, from_pandas=True).cast(\n                self._pa_array.type\n            )\n            return self._from_pyarrow_array(result_pa)\n\n        result: Self | npt.NDArray[np.object_]\n        if pa.types.is_string(self._pa_array.type) or pa.types.is_large_string(\n            self._pa_array.type\n        ):\n            try:\n                result = self._evaluate_op_method(other, op, ARROW_ARITHMETIC_FUNCS)\n            except (pa.ArrowInvalid, pa.ArrowTypeError):\n                result = self._str_arith_method_object_fallback(other, op)\n        else:\n            result = self._evaluate_op_method(other, op, ARROW_ARITHMETIC_FUNCS)","sourceCodeStart":1271,"sourceCodeEnd":1307,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/arrow/array.py#L1271-L1307","documentation":"Raised by _arith_method when adding/subtracting a BaseOffset (DateOffset) to a pyarrow date32/date64 array and the offset produces intra-day (non-midnight) timestamps. The code casts dates to timestamp[us], applies the offset via DatetimeArray, then checks is_normalized; if the result has a time component it cannot be represented back as a pure date, so pandas raises TypeError.","triggerScenarios":"`date_arr + pd.DateOffset(hours=5)`, `date_arr + pd.Timedelta('1h')` style offsets, or `date_arr + pd.offsets.Hour()` on a date32[pyarrow]/date64[pyarrow] array. Any offset whose n != 0 for sub-day units (hour/minute/second) fails the normalization check.","commonSituations":"Storing dates (not timestamps) in pyarrow date types then adding time-aware offsets; mixing pandas DateOffset semantics with pyarrow date types; assuming DateOffset(days=1) is fine but accidentally passing a BusinessHour offset.","solutions":["Cast the array to timestamp[pyarrow] before applying time-aware offsets.","Use only day-granular offsets with date types: pd.DateOffset(days=1).","Convert to datetime64[ns] for full temporal arithmetic.","Normalize the offset result or strip time after operating on timestamps."],"exampleFix":"# before\nshifted = date_arr + pd.DateOffset(hours=5)  # TypeError\n# after\nshifted = date_arr.astype('timestamp[us][pyarrow]') + pd.DateOffset(hours=5)","handlingStrategy":"type-guard","validationCode":"import pyarrow as pa\nfrom pandas.core.arrays.arrow import ArrowExtensionArray\n\ndef shift_dates(arr, offset):\n    if isinstance(arr, ArrowExtensionArray):\n        t = arr._pa_array.type\n        if pa.types.is_date(t) and not getattr(offset, 'is_on_offset', lambda ts: True).__call__(None) if False else not _is_day_granular(offset):\n            arr = arr.astype('timestamp[us][pyarrow]')\n    return arr + offset\n\ndef _is_day_granular(offset):\n    return getattr(offset, '_use_relativedelta', False) or offset.nanos == 0 and (offset.days != 0 or offset.delta == 0)\n\nout = shift_dates(date_arr, pd.DateOffset(hours=5))","typeGuard":"import pyarrow as pa\nfrom pandas.core.arrays.arrow import ArrowExtensionArray\n\ndef needs_timestamp_cast_for_offset(arr, offset) -> bool:\n    if not isinstance(arr, ArrowExtensionArray):\n        return False\n    if not pa.types.is_date(arr._pa_array.type):\n        return False\n    # any sub-day component?\n    return getattr(offset, 'nanos', 0) != 0 or getattr(offset, '_hours', 0) != 0 or getattr(offset, '_minutes', 0) != 0 or getattr(offset, '_seconds', 0) != 0","tryCatchPattern":"try:\n    out = date_arr + offset\nexcept TypeError as e:\n    if 'intra-day' in str(e):\n        out = date_arr.astype('timestamp[us][pyarrow]') + offset\n    else:\n        raise","preventionTips":["Cast pyarrow date arrays to timestamp before applying time-aware offsets.","Reserve date32/date64 for pure-day arithmetic.","Validate offset granularity against the array's temporal resolution."],"tags":["pyarrow","date-arithmetic","dateoffset","dtype-mismatch"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}