Disclosure: I maintain Cronbell, a heartbeat monitor that evaluates cron schedules in a timezone. The behaviour below is general; the outputs are from my own implementation, so check how your scheduler treats these cases.
Two nights a year, local wall-clock time lies to schedulers.
Spring forward: a time that does not exist. In Europe/Amsterdam the clocks jump from 02:00 to 03:00 on 2027-03-28, so 30 2 * * * has no 02:30 that day. In my tests the next run after 2027-03-27 is 2027-03-29 02:30 local (00:30 UTC). The same happens in America/New_York on 2027-03-14. Some cron daemons run skipped jobs right after the jump instead, others skip them; this is worth looking up for yours.
Fall back: a time that happens twice. On 2026-10-25 Amsterdam repeats 02:00-03:00. 30 2 * * * could fire at 00:30 UTC (CEST) or at 01:30 UTC (CET). I treat the first as the real one and skip the repeat, so the job runs once. That gives a related quirk: 0 * * * * is evaluated once for the repeated 02:00 hour, so after 02:30 CEST the next expected run is 03:00 CET (02:00 UTC), not an extra one.
Consequences for monitoring
- Fixed-interval monitors ("expect a ping every 24h") drift against a local-time cron for two days a year: either false alarms or a late one.
- Evaluate the cron expression in the job's own timezone, and set a grace period of at least an hour for jobs near 02:00-03:00 local.
- Safest of all: schedule jobs at times that are never skipped or repeated (for example 04:00 local), or run the host in UTC.
I found a real bug while writing this: my own implementation returned the later of the two occurrences on the fall-back night, which pushed one day's deadline back an hour. It is fixed and now has a regression test for these cases. If you maintain a scheduler, test your overlap case.
Related copy-paste heartbeat examples for crontab, systemd timers and Kubernetes (including timeZone): https://github.com/jinqo/cron-heartbeat-snippets
How does your cron or systemd timer behave on the repeated hour? I'd like to compare notes.


