Cron and time zones: why a job runs at another hour
Updated 16 October 2026
Cron follows the schedule in the time zone of the system where it runs, which may not be yours. When a job set for 08:00 runs at 11:00, or an hour early after a change of season, the cause is usually here.
Which time zone cron uses
The system’s, as it was when cron started. To see it on the server:
timedatectl | grep "Time zone"
date
In a container, without timedatectl, date shows the time and the abbreviation of the zone. Compare it with the hour you expect: if the server is in UTC and you wrote the schedule in your local time, the difference is your offset from UTC.
Change the server’s time zone
sudo timedatectl set-timezone America/Santiago
sudo systemctl restart cron # crond on RHEL, Fedora and Rocky
Restart cron after the change. On Debian and Ubuntu, the jobs see the new time right away, but cron keeps following the schedule in the old zone until it restarts.
Changing the server’s zone also changes the times in its logs and in the other programs that run there. The other option is to leave the server in UTC and write the schedule in UTC: in the cron tester, choose a time zone to see when an expression runs there.
They are different goals. A server in UTC has no daylight saving time, but a schedule fixed in UTC runs at another local hour when your zone changes its clocks. If the job must run at 08:00 local time all year, keep its schedule in the local zone, with one of the options below.
A time zone for one crontab
-
cronie (RHEL, Fedora, Rocky, AlmaLinux) accepts
CRON_TZat the top of the crontab. The lines below it follow that zone, and the logs keep the server’s time:CRON_TZ=America/Santiago 0 8 * * 1-5 /path/to/report.sh -
The cron of Debian and Ubuntu doesn’t. A
TZ=line in the crontab only changes the time zone of the commands, not when they run. Its manual suggests running the job every hour and checking the time in the command. Check the day there too: the day fields are still read in the server’s zone, and when it’s already Saturday in UTC it can still be Friday in Santiago.TZ=America/Santiago 0 * * * * [ "$(date +\%H)" = 08 ] && [ "$(date +\%u)" -le 5 ] && /path/to/report.shdate +%ugives the day of the week, from 1 (Monday) to 7 (Sunday), in the zone ofTZ. The%are escaped with\: in a crontab line, a%alone ends the command.
Docker, Kubernetes and systemd
-
In a Docker container, cron uses the container’s zone, usually UTC. Install
tzdataand setTZwhen you start it: the details are in how to run cron jobs in a Docker container. -
A Kubernetes
CronJobtakes its time zone inspec.timeZone, since Kubernetes 1.27. Without it, the schedule follows the zone of the cluster’s controller manager, usually UTC:spec: schedule: "0 8 * * 1-5" timeZone: "America/Santiago" -
A systemd timer accepts the zone in
OnCalendar.systemd-analyze calendarshows the next run, also in UTC:OnCalendar=Mon..Fri *-*-* 08:00:00 America/Santiago
Daylight saving time
The cron of Debian and Ubuntu, and cronie, handle a change of less than three hours in a special way, but only for the jobs that run at a specific hour:
- When the clock moves forward, the jobs that fell in the skipped time run right after the change. A job at 02:30 in a zone that jumps from 02:00 to 03:00 runs at about 03:00.
- When the clock moves back, the jobs that fall in the repeated time don’t run twice.
-
The jobs with
*in the hour or the minute, like every 15 minutes or every hour, follow the new time as usual.
For a job that must run exactly once a day at a precise hour, avoid the hour of the change in your zone. If what matters is the hour in UTC, keep its schedule in UTC, which has no daylight saving time. Other schedulers, like systemd or Kubernetes, have their own rules: check their documentation.
Know when it runs at another hour
In CronDrive, choose the same time zone that the scheduler uses to read the cron expression: the server’s, the one in CRON_TZ, the container’s or the one in spec.timeZone. The form shows the current time in that zone, to compare it with date where the job runs. If the job then runs at another hour and falls outside the waits you set, CronDrive tells you that it didn’t start or didn’t finish on time.