ToolBoxOnline
Developer

Cron and Daylight Saving Time: When a Nightly Job Runs Twice, or Not at All

Your cron job ran an hour early. Then it didn't run. Daylight saving breaks naive cron expressions — and there's a second trap hiding in day-of-month vs day-of-week nobody expects.

croncron parserdaylight saving timecron schedulingcron gotchas

You scheduled a database backup for 2:00 a.m. every night. After the time change, it runs at 1:00 a.m. Then your site is down because a report ran twice. The crontab looks perfect. The problem isn't your expression — it's that cron doesn't know what time is.

Cron Is a Dumb Clock

A cron expression just says "run when the wall clock matches." It has no concept of daylight saving time. When clocks spring forward, the hour from 2:00 to 3:00 doesn't exist — a job at 0 2 * * * simply doesn't fire. When clocks fall back, 1:30 a.m. happens twice — a job at 30 1 * * * runs twice. Most operators hit this exactly once and then swear forever at the scheduler.

The Fix Is Boring and Reliable: UTC

Counter-intuitive but true: the way to make cron immune to DST is to not use your local timezone at all. Run jobs in UTC (TZ=UTC in the crontab, or the platform default on managed schedulers) and the clock never jumps. If a job genuinely needs to run at a local time — "9 a.m. for the East Coast" — that's a business-time problem, and the schedule changes at DST boundaries by design. Decide up front which hours are "server time" and which are "human time," and never mix them in one crontab.

The Second Trap: Day-of-Month AND Day-of-Week

The less famous gotcha lives in fields 3 and 5. In standard cron, if you restrict BOTH the day-of-month and the day-of-week, the job runs when EITHER matches — they're OR'd, not AND'd. So 0 2 1 * 1 does not mean "the first of the month when it's a Monday." It means "every first of the month AND every Monday." A real "first Monday of the month" needs extra logic. Before you deploy, run the expression through a cron parser and read the exact matches it reports — and when you're thinking in epoch seconds, the unix timestamp tool keeps the numbers straight.

Timezone mistakes are the classic source of "why did my job run at 3 a.m." — we covered them in our guide to cron timezone traps. Schedule in UTC, watch the OR logic, and verify every expression before it fires.

Tools mentioned in this article

Compartir esta herramienta