Fix time zone normalization bug in interval schedules #19301
Merged
+59
−38
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
We discovered a regression in interval schedules after the pendulum →
datetime/zoneinforefactor. When the schedule JSON contains a fixed-offset anchor such as"2024-07-01T01:15:00+09:00"alongside a non-UTC timezone like"Asia/Tokyo", the scheduler drifts runs by the offset—so 01:15 JST became 10:15 JST.Changes
The culprit is the new tzinfo "normalization." For tzinfos that aren't
ZoneInfo, the code called.tzname()to get a timezone name; offset tzinfos return strings like"UTC+09:00", which fails when trying to create aZoneInfofrom that invalid key.The fix uses
.astimezone(ZoneInfo(target_timezone))for offset-based tzinfos, which preserves both the absolute instant and microsecond precision. Naive datetimes still assume the schedule's timezone, and trueZoneInfoobjects continue down the existing.to_tz()path.Testing
Added regression test
test_offset_anchor_preserves_local_hourwhich:Test confirmed:
All existing interval schedule tests and scheduler service tests pass on Python 3.13.
🤖 Generated with Claude Code