Lee-W opened a new pull request, #75847:
URL: https://github.com/apache/airflow/pull/75847
## Why
An hourly cron that skips days, for example `0 * * * 1-5`, computes the next
run after Friday 23:00 by treating the wall-clock gap to Monday 00:00 as
elapsed time. That gap is 49 hours, but if a DST change falls over the weekend
the real elapsed time is 50 hours (clocks go back) or 48 hours (clocks go
forward). The next run is therefore an hour off:
| Timezone | current (UTC) | Before | After | After (local) |
|---|---|---|---|---|
| Europe/Berlin (fall back 2026-10-25) | 2026-10-23T21:00Z (Fri 23:00 CEST)
| 2026-10-25T22:00Z | 2026-10-25T23:00Z | Mon 00:00 CET |
| America/Chicago (fall back 2026-11-01) | 2026-10-31T04:00Z (Fri 23:00 CDT)
| 2026-11-02T05:00Z | 2026-11-02T06:00Z | Mon 00:00 CST |
| Australia/Sydney (fall back 2026-04-05) | 2026-04-03T12:00Z (Fri 23:00
AEDT) | 2026-04-05T13:00Z | 2026-04-05T14:00Z | Mon 00:00 AEST |
| Europe/Berlin (spring forward 2027-03-28) | 2027-03-26T22:00Z (Fri 23:00
CET) | 2027-03-28T23:00Z | 2027-03-28T22:00Z | Mon 00:00 CEST |
Before the fix the result is an hour early when clocks go back and an hour
late when clocks go forward.
The elapsed-time shortcut exists only so that an hourly schedule walks
through the repeated hour when clocks go back. It does not need to apply to
gaps longer than one hour.
## What
- Limit the elapsed-time shortcut in `CronMixin`
(`airflow-core/src/airflow/timetables/_cron.py`) to intervals of at most one
hour.
- For longer intervals, convert the wall-clock result directly to the
timezone. This keeps both occurrences of a repeated hour and ignores wall-clock
times that do not exist when clocks go forward.
- Add a helper, `_localize_all_folds`, that returns every valid localization
of a naive datetime. It relies on pendulum's `Timezone.convert()` honouring
`fold` (the project requires pendulum>=3.1.0); that was only verified against
the installed version, so the helper has its own unit test.
This does not fix every DST edge case. A brute-force comparison (below)
still found cases that are wrong both before and after this change: 234 for
`_get_next` and 106 for `_get_prev`, in zones such as Cairo, Lord_Howe,
Santiago and Beirut, with Lord_Howe and LHI (30-minute DST) making up most of
them. They are not introduced here and are not addressed in this PR; I suggest
tracking them in a separate issue.
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
<!--
Thank you for contributing!
Please provide above a brief description of the changes made in this pull
request.
Write a good git commit message following this guide:
https://chris.beams.io/posts/git-commit/
Please make sure that your code changes are covered with tests.
And in case of new features or big changes remember to adjust the
documentation.
For user-facing UI changes, please attach before/after screenshots (or a
short
screen recording) so reviewers can assess the visual impact.
Feel free to ping (in general) for the review if you do not see reaction for
a few days
(72 Hours is the minimum reaction time you can expect from volunteers) - we
sometimes miss notifications.
In case of an existing issue, reference it using one of the following:
* closes: #ISSUE
* related: #ISSUE
-->
---
##### Was generative AI tooling used to co-author this PR?
<!--
If generative AI tooling has been used in the process of authoring this PR,
please
change below checkbox to `[X]` followed by the name of the tool, uncomment
the "Generated-by".
-->
- [x] Yes (please specify the tool below)
<!--
Generated-by: [Claude] following [the
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
-->
---
* Read the **[Pull Request
Guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#pull-request-guidelines)**
for more information. Note: commit author/co-author name and email in commits
become permanently public when merged.
* For fundamental code changes, an Airflow Improvement Proposal
([AIP](https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Improvement+Proposals))
is needed.
* When adding dependency, check compliance with the [ASF 3rd Party License
Policy](https://www.apache.org/legal/resolved.html#category-x).
* For significant user-facing changes create newsfragment:
`{pr_number}.significant.rst`, in
[airflow-core/newsfragments](https://github.com/apache/airflow/tree/main/airflow-core/newsfragments).
You can add this file in a follow-up commit after the PR is created so you
know the PR number.
--
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]