AdroitPad
Back to blog

REFERENCE · 7 MIN READ

Cron gotchas, part 2: timezones and Daylight Saving Time

The timezone traps that make a correct-looking schedule drift or fire twice.

Which clock owns the schedule?

A cron expression is evaluated by a clock, and the most important question is whose clock. A server configured for UTC, a container inheriting UTC, and a developer reading the schedule in Pacific Time can all interpret “9 AM” differently. Make the timezone explicit in the scheduler or convert the requirement to UTC and document the conversion.

DST is not a corner case

When clocks jump forward, a local time can never occur; when they fall back, an hour occurs twice. A 02:30 job may be skipped in spring or duplicated in autumn, depending on the scheduler. Jobs should be idempotent, and critical schedules should record the intended timezone and next fire times rather than relying on mental arithmetic.

Test transitions with a timezone-aware library and a table of expected timestamps. Also check the day-of-month/day-of-week OR rule from the original cron article, month-end dates, leap years, and missed-run behavior before production.

Practical follow-up

A schedule that sends a daily report should usually anchor to the recipient’s named timezone, not the server’s current offset. Store the zone identifier, such as America/Los_Angeles, because a numeric offset cannot describe future DST changes.

For repeated times, persist an execution identity containing the local date and intended slot. The worker can then safely ignore a second delivery for the same identity while still recording that the clock transition occurred.

01:30scheduled
02:00 skippedspring forward
03:00next valid time
Concept diagram · dst timeline

Conclusion

A schedule is only correct when its clock and timezone are explicit. The timeline shows why a local timestamp can be skipped or encountered twice when daylight saving rules change. Treat the named timezone as part of the job configuration rather than deriving it from the server at runtime. Record the intended local date and execution slot so retries can be made idempotent. Test spring-forward and fall-back transitions with real timezone data before launch. A small amount of calendar-aware modeling prevents silent drift, duplicate notifications, and missed operational work.

Download free