2026-10-15 · 6 min read · Rahul Chitturi
- cron
- scheduling
- timezones
A cron line has two clocks. One clock decides when the five fields match. The other clock is the timezone the process sees after it starts. People set TZ in the crontab, watch the job print a local time, and assume the schedule moved with it.
On cronie, CRON_TZ is the schedule zone and TZ is only the job environment. On some other Vixie-derived crons, TZ is what the daemon reads for the schedule and CRON_TZ is ignored. A preamble copied from the other host does not do the job you think it does.
Read the manual for the binary you run
Identify cron or crond and open that version's crontab(5). Put the schedule variable on its own line above the job, not inside the command. Use an IANA name such as America/New_York. A fixed abbreviation can mean one offset all year, including through daylight-saving time.
The daemon's system zone still matters for log timestamps. cronie writes logs in the zone where the daemon runs, even when CRON_TZ schedules the table. A log line an hour off is not proof the job fired an hour off until you convert that line.
- Record whether the host is cronie or another cron.
- Record CRON_TZ, TZ, and the system zone separately.
- Keep the five fields free of the variable name.
- Prefer an IANA name over EST or IST.
Do not paste CRON_TZ into another scheduler
A Kubernetes CronJob schedule is the five fields. The zone belongs in spec.timeZone, which is a different field. A CRON_TZ= prefix inside schedule is not a valid expression there. systemd OnCalendar is a different grammar and does not read CRON_TZ either.
A user crontab is five fields and a command. A system crontab adds a user column between the fields and the command. Moving a line between those files shifts the command into the user column.
Preview the zone you think the daemon uses
Paste the five fields into Flashman's cron tool and set the timezone to the IANA name you believe schedules the job. The tool lists the next five instants as UTC. It does not read your crontab's CRON_TZ line for you, and it does not reproduce every daemon's policy for a skipped or repeated local hour.
Convert a log timestamp in the timestamp tool and diff it with the first preview. If they disagree, the daemon is not in the zone you typed. Write the human schedule above the line in the repo so the next edit can see which clock was supposed to move.