Cron operations guide
Cron Time Zones and DST: Plan for Clock Changes
Learn which clock a five-field cron schedule uses, why daylight saving time can skip or repeat a job, and how to test a schedule before production.
Understand the input
Identify what must survive.
Choose the trade-off
Match settings to the real task.
Verify the output
Check the result before replacing anything.
A cron expression contains a schedule, not a time zone
The familiar five fields describe minute, hour, day of month, month, and day of week. An expression such as 0 9 * * 1-5 means 09:00 on weekdays according to the clock cron is using. The expression itself does not say “Bangkok,” “UTC,” or “New York.”
Before using the crontab generator, write the requirement with an explicit zone: “09:00 Asia/Bangkok every weekday” or “09:00 UTC.” A server migration, container image, or administrator setting can otherwise move the job while leaving the five fields unchanged.
Find the clock your cron daemon actually uses
- Check the server clock with
dateand, on systemd systems,timedatectl. - Inspect the crontab for
CRON_TZ. In implementations that support it, this variable sets the zone used to interpret following entries. - Check platform documentation. A managed scheduler may use UTC even when an interactive shell shows local time.
- Log an ISO timestamp and zone from the job itself. The process environment can differ from the scheduler display.
CRON_TZ=Asia/Bangkok
0 9 * * 1-5 /opt/reports/daily.sh >> /var/log/daily-report.log 2>&1Do not assume every cron implementation accepts CRON_TZ. If portability matters, document the daemon and operating system you tested, or keep the host clock in UTC and convert the business requirement deliberately.
Daylight saving time creates a missing hour and a repeated hour
In zones that advance the clock, some local times never occur. A job scheduled inside that gap does not match and may not run. When the clock moves backward, a range of local times occurs twice; a job in that range may run twice. The Cronie crontab manual documents both behaviors explicitly.
| Requirement | Safer design | Reason |
|---|---|---|
| Exactly once per calendar day | Schedule outside the transition window and make the task idempotent | The clock can still change or the host can restart |
| Every fixed elapsed interval | Use an interval-aware service timer or queue | Local clock hours are not always 60 minutes apart |
| At a business-local wall time | Use the named IANA zone and handle missed/repeated executions | A fixed UTC offset changes relative to local time across DST |
| Globally consistent batch cutoff | Schedule in UTC | UTC has no seasonal clock jump |
Make a repeated run harmless
Cron starts processes; it does not know whether the business action has already happened. An idempotent job records the period it is processing and refuses to apply the same effect twice. For example, use a database uniqueness constraint on report_date, write output to a temporary file before an atomic rename, or acquire a lock before starting.
flock -n /run/lock/daily-report.lock /opt/reports/daily.sh --for-date "$(date +%F)"A lock prevents overlapping processes, but it does not by itself prove the business result was committed. Keep a durable completion marker when duplicate billing, email, or deletion would be costly.
Two cron field details that cause false expectations
First, a traditional cron job is commonly executed by /bin/sh, not necessarily the interactive shell where you tested a command. Use absolute paths, set required environment variables, and run the exact script under the cron user.
Second, when both day-of-month and day-of-week fields are restricted, traditional cron runs when either field matches. 0 9 1 * 1 commonly means the first day of every month or every Monday—not only a Monday that is also the first.
Production checklist
- Record the required wall time and its named IANA time zone.
- Confirm the cron implementation, server zone, cron user, shell, and working directory.
- Inspect the next DST transition for that zone and decide what a missed or repeated run should do.
- Use absolute command paths, durable logs, and a failure alert.
- Make the action idempotent and guard against overlapping runs.
- Test the command under the real user before installing the schedule.
Sources
- crontab(5) manual page — field behavior, shell defaults,
CRON_TZ, and DST handling. - IANA Time Zone Database — named zones and the source of changing civil-time rules.