Skip to content

fix(cron): handle naive legacy timestamps in due-job checks#929

Closed
teknium1 wants to merge 1 commit intomainfrom
fix/cron-naive-timestamps
Closed

fix(cron): handle naive legacy timestamps in due-job checks#929
teknium1 wants to merge 1 commit intomainfrom
fix/cron-naive-timestamps

Conversation

@teknium1
Copy link
Contributor

Summary

Cherry-picked from PR #807 by @0xNyk, rebased onto current main with added tests.

The Bug (#806)

_ensure_aware() used dt.replace(tzinfo=hermes_tz) for naive datetimes, but those timestamps were created with datetime.now() (system local time). When HERMES_TIMEZONE differs from the system timezone, this reinterprets the wall-clock time in the wrong timezone, shifting the absolute moment in time.

Example: System in IST (UTC+5:30), HERMES_TIMEZONE=US/Eastern (UTC-5):

  • Naive "5 min ago" = 17:25 (IST wall time)
  • Old code stamps as 17:25 EST (= 22:25 UTC) — 10+ hours in the future
  • _hermes_now() = 07:00 EST — job appears NOT due ❌

The Fix

  • Naive datetimes: Interpret as system-local wall time first, then convert to Hermes tz
  • Aware datetimes: Normalize to Hermes tz via astimezone() for consistent comparisons
  • No regression when system tz == Hermes tz (behavior is identical)

Tests Added (3 new)

  • test_ensure_aware_naive_preserves_absolute_time — verifies correct local→Hermes conversion
  • test_ensure_aware_normalizes_aware_to_hermes_tz — verifies aware datetime normalization
  • test_get_due_jobs_naive_cross_timezone — integration test with Pacific/Midway (UTC-11) to catch the false not-due scenario

Test Results

64 passed, 3 skipped (timezone + cron suites)

Fixes #806
Closes #807

Cherry-picked from PR #807 by 0xNyk, rebased onto current main.

When HERMES_TIMEZONE differs from system local timezone, naive (legacy)
timestamps were misinterpreted by _ensure_aware() — it stamped them
with the Hermes timezone via replace(tzinfo=...), but they were created
using datetime.now() (system local time). This could shift the absolute
time and cause overdue jobs to appear not-due.

Fix: interpret naive datetimes as system-local wall time first, then
convert to Hermes timezone. Already-aware datetimes are normalized to
Hermes timezone for consistent comparisons.

Added 3 tests:
- _ensure_aware preserves absolute time for naive datetimes
- _ensure_aware normalizes aware datetimes to Hermes tz
- get_due_jobs detects naive past timestamps as due even when Hermes tz
  is far behind system local tz (the scenario from #806)

Fixes #806

Co-authored-by: Nyk <0xnykcd@googlemail.com>
@teknium1
Copy link
Contributor Author

Closing as superseded. The substantive cron fix was already merged via PR #949, and the one remaining useful regression test from the follow-up work has now been merged via PR #1319.

@teknium1 teknium1 closed this Mar 14, 2026
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.

[Bug]: get_due_jobs may skip legacy naive timestamps under non-local Hermes timezone

2 participants