DeviousCardi opened a new pull request, #53325: URL: https://github.com/apache/arrow/pull/53325
### Rationale for this change There is currently no kernel for `timestamp + interval`, so e.g. "add one day to a zoned timestamp, keeping the wall clock time" requires a round trip through pandas (see #47400). ### What changes are included in this PR? New kernels for `add`, `add_checked`, `subtract` and `subtract_checked`: - `timestamp(unit, tz) ± month_interval / day_time_interval / month_day_nano_interval -> timestamp(unit, tz)`, for all four units, with or without a timezone - `add` / `add_checked` also accept the interval as the first argument Semantics follow the discussion in the issue (Pandas' `DateOffset`): - Months and days are calendar units applied to the local time of the timestamp, so `2025-03-08 09:30 EST + 1 day = 2025-03-09 09:30 EDT`. - The sub-day part (milliseconds of a `day_time_interval`, nanoseconds of a `month_day_nano_interval`) is a fixed duration, so `2025-03-08 09:30 EST + 24h = 2025-03-09 10:30 EDT`. - `add` applies months, then days, then the sub-day part. `subtract` applies the sub-day part first, so subtracting "1 day 24 hours" undoes adding it (the mixed-interval examples in the issue). Months are applied before days in both directions, as in `DateOffset` and PostgreSQL. - Adding months clamps the day of month (Jan 31 + 1 month = Feb 28/29). - If the resulting local time is ambiguous or doesn't exist (DST overlap or gap), an `Invalid` error is returned, with the same messages as the existing `ZonedLocalizer::ConvertLocalToSys`. This is also what pandas does for a tz-aware `Series`/`DatetimeIndex` + `DateOffset` (a scalar `Timestamp` silently resolves instead). The issue doesn't settle this point. If wanted, a follow-up could add an option to choose `earliest`/`latest`/shift-forward like `AssumeTimezoneOptions`. - A sub-day part that isn't a multiple of the timestamp unit (e.g. 1 ns added to `timestamp[s]`) returns `Invalid`. - The `_checked` variants return `Invalid` on int64 overflow; the unchecked variants wrap around like the other arithmetic kernels. Calendar arithmetic uses 64-bit year arithmetic, so the full range of `timestamp[s]` is supported. The timezone lookups use the existing `LocateZone`/`time_zone::get_info` machinery from `temporal_internal.h`. `ArithmeticFunction::DispatchBest` no longer applies implicit temporal promotion when one of the arguments is an interval. Otherwise `date32 + interval` would be silently cast to `timestamp[s] + interval`. Dates are not supported yet; I'd suggest doing them in a follow-up once we agree on what `date + interval with a sub-day part` should return. ### Are these changes tested? Yes: - C++ (`scalar_temporal_test.cc`): month-end clamping, leap years, negative intervals, nulls, all units and all three interval types, both argument orders. DST transitions are covered in America/New_York, Europe/London and Australia/Lord_Howe (30 min DST), including results that land just after a gap or overlap and results that fall inside one (errors), plus a fixed-offset timezone. Error tests cover sub-unit and overflow cases. The expected DST values were checked against pandas 3.0.6. - Python (`test_compute.py`): parity with `pandas.DateOffset` + `Timedelta` across timezones and units, and the same DST gap/overlap errors as pandas. ### Are there any user-facing changes? Yes, new kernels for `add`/`subtract` (documented in `compute.rst`). Existing kernels are unchanged. --- AI usage disclosure: I used an AI coding assistant (Claude) for this PR. It drafted most of the kernel code, the C++ and Python tests, and the docs paragraph. I reviewed all of it, and the expected DST values in the tests were checked against pandas independently of the kernel. The 64-bit calendar helpers (`DaysFromCivil`/`CivilFromDays`) follow Howard Hinnant's public-domain date algorithms, which are linked in a comment. * GitHub Issue: #47400 -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
