fix(cron): respect configured timezone for naive timestamps - #12241
fix(cron): respect configured timezone for naive timestamps#12241Julientalbot wants to merge 2 commits into
Conversation
…schedule() Problem: When a user creates a cron job with a naive timestamp like "2026-04-18T17:30", parse_schedule() calls dt.astimezone() which interprets it in the server's system timezone. On most VPS this is UTC, so "17:30" fires at 17:30 UTC — not the user's local 17:30. This is a silent bug: the cron job fires, but hours off from when the user expected. For users in GMT+4 (Reunion), that's 4 hours late. For GMT+5:30 (India), 5.5 hours late. The infrastructure already exists — hermes_time.get_timezone() reads the timezone from config.yaml or HERMES_TIMEZONE env var — but parse_schedule() never uses it. Fix: In parse_schedule(), when a naive timestamp is encountered, use _hermes_get_tz() to assign the configured timezone instead of the system timezone. Falls back to the original astimezone() behavior when no timezone is configured. Also adds a "timezone" section to the setup wizard (hermes setup timezone) so users can configure this during initial setup. The wizard auto-detects the system timezone and validates the IANA ID. Changes: - cron/jobs.py: import get_timezone, use it for naive timestamps - hermes_cli/setup.py: add setup_timezone() function and section
Code Review: fix(cron): respect configured timezone for naive timestampsSummaryThe core fix in Issues
VerdictRequest changes — The core fix is correct, minimal, and backward-compatible. However, this PR must not merge without at least one or two unit tests covering the actual bug fix. Once tests are added, this is a clear approve. |
Addresses review feedback on NousResearch#12241: - Add 4 tests for parse_schedule naive-timestamp tz handling: * uses configured tz (Asia/Kolkata → UTC+5:30 offset) * falls back to astimezone() when no tz configured * guards against non-tzinfo return from _hermes_get_tz() * preserves explicit tz-aware input unchanged - cron/jobs.py: isinstance(tzinfo) defensive check before dt.replace(), prevents opaque TypeError if get_timezone() ever returns a string - hermes_cli/setup.py: * prefer /etc/localtime symlink on macOS (no elevated privileges, works on newer macOS where systemsetup may require sudo) * Linux: add /etc/localtime fallback after timedatectl + /etc/timezone * catch ImportError separately for zoneinfo, narrow validation catch to (ZoneInfoNotFoundError, ValueError)
|
Thanks for the review @ParamChordiya — all valid. Just pushed 44a677e addressing everything: Tests (the main blocker) — 4 new tests in
All 11 Defensive typing (#5) — added macOS detection (#4) — now prefers reading
The unrelated |
|
Closing — stepping back from speculative PRs on this repo to focus on public artifacts I control. The cron timezone behavior is already handled locally on my fleet via config.yaml tz override. If anyone picks this up, happy to share the test cases. |
Problem
When a user creates a cron job with a naive timestamp like
"2026-04-18T17:30",parse_schedule()callsdt.astimezone()which interprets it in the server's system timezone. On most VPS/cloud servers this is UTC, so"17:30"fires at 17:30 UTC — not the user's local 17:30.This is a silent bug: the cron job fires, but hours off from when the user expected. Examples:
The infrastructure to fix this already exists —
hermes_time.get_timezone()reads the timezone fromconfig.yamlorHERMES_TIMEZONEenv var — butparse_schedule()never uses it.Fix
cron/jobs.py(2 lines changed): When a naive timestamp is encountered, use_hermes_get_tz()to assign the configured timezone instead of the system timezone. Falls back to the originalastimezone()behavior when no timezone is configured — zero breaking change.hermes_cli/setup.py(~80 lines added): Add atimezonesection to the setup wizard (hermes setup timezone) so users can configure their timezone during initial setup. Auto-detects the system timezone viatimedatectl(Linux) orsystemsetup(macOS) and validates the IANA ID.Testing
All 55 existing cron tests pass with the patch applied.
Example
Before (VPS in UTC, user in Europe/Paris):
After (with
timezone: "Europe/Paris"in config.yaml):If no timezone is configured → behavior unchanged (uses system timezone).