Skip to content

Normalize timezone-aware create_timer fire_at to naive UTC#1167

Open
acroca wants to merge 1 commit into
dapr:mainfrom
acroca:tz-awareness
Open

Normalize timezone-aware create_timer fire_at to naive UTC#1167
acroca wants to merge 1 commit into
dapr:mainfrom
acroca:tz-awareness

Conversation

@acroca

@acroca acroca commented Jul 17, 2026

Copy link
Copy Markdown
Member

Timers created with a timezone-aware fire_at are now explicitly normalized to naive UTC in create_timer / create_timer_internal before the CreateTimerAction is built. Previously the scheduled instant was correct only implicitly, relying on protobuf's FromDatetime to normalize aware datetimes at serialization time; making the conversion explicit in the SDK guarantees the naive-UTC invariant that the rest of the worker assumes (current_utc_datetime is always naive UTC) and protects any future logic that compares fire_at against the workflow clock. Also adds executor-level regression tests covering scheduling with an aware fire_at (same absolute instant as its naive-UTC equivalent) and clean replay against history recorded in naive UTC.

A timezone-aware fire_at is now converted to naive UTC in
create_timer_internal before the CreateTimerAction is built. The wire
value was previously correct only implicitly — protobuf's
Timestamp.FromDatetime normalizes aware datetimes — so this makes the
naive-UTC invariant explicit in SDK code, keeping fire_at safe to
compare against current_utc_datetime (always naive UTC) if such
comparisons are ever added. The isinstance guard is needed because
fire_at may also be the sentinel Timestamp used for indefinite
external-event waits.

Adds executor-level regression tests: an aware fire_at schedules at the
same absolute instant as its naive-UTC equivalent, and replays cleanly
against history recorded in naive UTC.

Signed-off-by: Albert Callarisa <albert@diagrid.io>
@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.86%. Comparing base (3457d0a) to head (23ddc52).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1167      +/-   ##
==========================================
+ Coverage   82.78%   82.86%   +0.07%     
==========================================
  Files         123      123              
  Lines       10127    10129       +2     
==========================================
+ Hits         8384     8393       +9     
+ Misses       1743     1736       -7     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes timer scheduling behavior in the workflow durabletask worker explicit and deterministic by normalizing timezone-aware fire_at datetimes to naive UTC before constructing the CreateTimerAction. This aligns timer inputs with the worker’s existing assumption that current_utc_datetime is always naive UTC, avoiding reliance on protobuf serialization side-effects and protecting future clock-comparison logic.

Changes:

  • Normalize timezone-aware datetime values passed to create_timer_internal into naive UTC (astimezone(timezone.utc) + replace(tzinfo=None)).
  • Add executor-level regression tests to ensure timezone-aware fire_at schedules the same absolute instant as its naive-UTC equivalent.
  • Add a replay-compatibility test to ensure clean replay against history recorded in naive UTC (sidecar behavior).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
dapr/ext/workflow/_durabletask/worker.py Explicitly normalizes aware datetimes to naive UTC prior to building timer actions.
tests/ext/workflow/durabletask/test_orchestration_executor.py Adds regression tests for correct scheduling and replay behavior with timezone-aware fire_at.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@acroca
acroca marked this pull request as ready for review July 17, 2026 06:04
@acroca
acroca requested review from a team as code owners July 17, 2026 06:04

@sicoyle sicoyle left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm - thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants