JustUtils

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.

By JustUtils10 minute readReviewed
A safer three-step decision path
STEP 1

Understand the input

Identify what must survive.

STEP 2

Choose the trade-off

Match settings to the real task.

STEP 3

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

  1. Check the server clock with date and, on systemd systems, timedatectl.
  2. Inspect the crontab for CRON_TZ. In implementations that support it, this variable sets the zone used to interpret following entries.
  3. Check platform documentation. A managed scheduler may use UTC even when an interactive shell shows local time.
  4. 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>&1

Do 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.

RequirementSafer designReason
Exactly once per calendar daySchedule outside the transition window and make the task idempotentThe clock can still change or the host can restart
Every fixed elapsed intervalUse an interval-aware service timer or queueLocal clock hours are not always 60 minutes apart
At a business-local wall timeUse the named IANA zone and handle missed/repeated executionsA fixed UTC offset changes relative to local time across DST
Globally consistent batch cutoffSchedule in UTCUTC 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