Cron y zonas horarias: por qué un job se ejecuta a otra hora
Actualizada el 16 de octubre de 2026
Cron sigue el horario en la zona horaria del sistema donde se ejecuta, que puede no ser la tuya. Cuando un job programado para las 08:00 se ejecuta a las 11:00, o una hora antes después de un cambio de horario, la causa suele estar aquí.
Qué zona horaria usa cron
La del sistema, como estaba cuando cron se inició. Para verla en el servidor:
timedatectl | grep "Time zone"
date
En un contenedor, sin timedatectl, date muestra la hora y la abreviatura de la zona. Compárala con la hora que esperas: si el servidor está en UTC y escribiste el horario en tu hora local, la diferencia es tu desfase con UTC.
Cambia la zona horaria del servidor
sudo timedatectl set-timezone America/Santiago
sudo systemctl restart cron # crond en RHEL, Fedora y Rocky
Reinicia cron después del cambio. En Debian y Ubuntu, los jobs ven la nueva hora de inmediato, pero cron sigue el horario en la zona anterior hasta que se reinicia.
Cambiar la zona del servidor también cambia las horas de sus logs y de los otros programas que corren ahí. La otra opción es dejar el servidor en UTC y escribir el horario en UTC: en el probador de cron, elige una zona horaria para ver cuándo se ejecuta una expresión ahí.
Son objetivos distintos. Un servidor en UTC no tiene horario de verano, pero un horario fijo en UTC se ejecuta a otra hora local cuando tu zona cambia la hora. Si el job tiene que ejecutarse a las 08:00 locales todo el año, deja su horario en la zona local, con alguna de las opciones de abajo.
Una zona horaria para un crontab
-
cronie (RHEL, Fedora, Rocky, AlmaLinux) acepta
CRON_TZal principio del crontab. Las líneas de abajo siguen esa zona, y los logs mantienen la hora del servidor:CRON_TZ=America/Santiago 0 8 * * 1-5 /ruta/al/reporte.sh -
El cron de Debian y Ubuntu no lo acepta. Una línea
TZ=en el crontab solo cambia la zona horaria de los comandos, no cuándo se ejecutan. Su manual sugiere ejecutar el job cada hora y revisar la hora en el comando. Revisa ahí también el día: los campos de días se siguen leyendo en la zona del servidor, y cuando en UTC ya es sábado, en Santiago todavía puede ser viernes.TZ=America/Santiago 0 * * * * [ "$(date +\%H)" = 08 ] && [ "$(date +\%u)" -le 5 ] && /ruta/al/reporte.shdate +%uda el día de la semana, de 1 (lunes) a 7 (domingo), en la zona deTZ. Los%van escapados con\: en una línea de crontab, un%solo termina el comando.
Docker, Kubernetes y systemd
-
En un contenedor de Docker, cron usa la zona del contenedor, normalmente UTC. Instala
tzdatay defineTZal iniciarlo: los detalles están en cómo ejecutar cron jobs en un contenedor de Docker. -
Un
CronJobde Kubernetes recibe su zona horaria enspec.timeZone, desde Kubernetes 1.27. Sin ella, el horario sigue la zona del controller manager del cluster, normalmente UTC:spec: schedule: "0 8 * * 1-5" timeZone: "America/Santiago" -
Un timer de systemd acepta la zona en
OnCalendar.systemd-analyze calendarmuestra la próxima ejecución, también en UTC:OnCalendar=Mon..Fri *-*-* 08:00:00 America/Santiago
El horario de verano
El cron de Debian y Ubuntu, y cronie, tratan de forma especial un cambio de menos de tres horas, pero solo para los jobs que se ejecutan a una hora específica:
- Cuando el reloj se adelanta, los jobs que caían en el tiempo saltado se ejecutan justo después del cambio. Un job a las 02:30 en una zona que salta de las 02:00 a las 03:00 se ejecuta cerca de las 03:00.
- Cuando el reloj se atrasa, los jobs que caen en el tiempo repetido no se ejecutan dos veces.
-
Los jobs con
*en la hora o en el minuto, como cada 15 minutos o cada hora, siguen la nueva hora como siempre.
Para un job que debe ejecutarse exactamente una vez al día a una hora precisa, evita la hora del cambio en tu zona. Si lo que importa es la hora en UTC, deja su horario en UTC, que no tiene horario de verano. Otros programadores de tareas, como systemd o Kubernetes, tienen sus propias reglas: revisa su documentación.
Entérate cuando se ejecute a otra hora
En CronDrive, elige la misma zona horaria que usa el programador para interpretar la expresión cron: la del servidor, la de CRON_TZ, la del contenedor o la de spec.timeZone. El formulario muestra la hora actual en esa zona, para compararla con date donde se ejecuta el job. Si después el job se ejecuta a otra hora y queda fuera de las esperas que configuraste, CronDrive te avisa que no se inició o no terminó a tiempo.