Los cinco campos
El cron clásico, el que usan el crontab de Linux, los CronJobs de Kubernetes y GitHub Actions, lee cinco campos de izquierda a derecha. Cada campo indica los valores en los que la tarea puede ejecutarse, y la tarea se ejecuta cada vez que todos los campos coinciden con la hora actual. Un asterisco significa cualquier valor.
| Posición | Campo | Valores permitidos | Nombres |
|---|---|---|---|
| 1 | Minuto | 0 a 59 | |
| 2 | Hora | 0 a 23 | |
| 3 | Día del mes | 1 a 31 | |
| 4 | Mes | 1 a 12 | JAN a DEC |
| 5 | Día de la semana | 0 a 7 (0 y 7 son domingo) | SUN a SAT |
Pruébalo aquí: Generador de expresiones cron
Abrir la herramienta completaCaracteres especiales
Con cuatro caracteres se cubren casi todas las programaciones. Se pueden combinar dentro de un mismo campo, por ejemplo 1-5,10 o 0-30/10. Los nombres de meses y días se escriben en inglés, como JAN o MON.
| Carácter | Significado | Ejemplo | Resultado |
|---|---|---|---|
| * | Todos los valores | * en el campo de la hora | Cada hora |
| , | Una lista de valores | 0,30 en el campo del minuto | En el minuto 0 y 30 |
| - | Un rango | 9-17 en el campo de la hora | Cada hora de las 9 a las 17 |
| / | Un paso | */15 en el campo del minuto | Cada 15 minutos: 0, 15, 30, 45 |
| / después de un valor | Paso desde un inicio | 5/20 en el campo del minuto | En el minuto 5, 25 y 45 |
| Atajo con @ | Una programación con nombre | @daily | Igual que 0 0 * * * |
Programaciones comunes
Estas expresiones se comprobaron con el generador de esta página. Copia la que más se acerque a lo que necesitas y ajusta los números.
| Expresión | Se ejecuta |
|---|---|
| * * * * * | Cada minuto |
| */5 * * * * | Cada 5 minutos |
| */15 * * * * | Cada 15 minutos |
| 0 * * * * | Al principio de cada hora |
| 30 * * * * | En el minuto 30 de cada hora |
| 0 */6 * * * | Cada 6 horas: 0:00, 6:00, 12:00, 18:00 |
| 0 0 * * * | Todos los días a medianoche |
| 0 9 * * * | Todos los días a las 9:00 |
| 0 9,17 * * * | Todos los días a las 9:00 y a las 17:00 |
| 0 9 * * 1-5 | A las 9:00 de lunes a viernes |
| */10 9-17 * * 1-5 | Cada 10 minutos en horario de oficina, de lunes a viernes |
| 0 22 * * 0,6 | A las 22:00 los sábados y domingos |
| 0 9 * * 1 | Todos los lunes a las 9:00 |
| 0 0 1 * * | El primer día de cada mes a medianoche |
| 0 0 1,15 * * | Los días 1 y 15 de cada mes |
| 0 0 1 */3 * | El primer día de cada tres meses (trimestral) |
| 0 0 1 1 * | Una vez al año, el 1 de enero a medianoche |
| 15 2 * * * | Todas las noches a las 2:15 |
| 0 12 * 6-8 * | Todos los días a mediodía en junio, julio y agosto |
| 0 8 1-7 * 1 | Cuidado: días 1 a 7 o cualquier lunes, ver abajo |
Día del mes y día de la semana a la vez
Esta es la regla que más gente pilla desprevenida. Cuando los dos campos de día están restringidos, el cron clásico se ejecuta los días que cumplen cualquiera de los dos, no ambos. Así, 0 8 1-7 * 1 no significa el primer lunes del mes: se ejecuta los días 1 a 7 y además todos los lunes. Del mismo modo, 0 0 13 * 5 se ejecuta cada día 13 y cada viernes, no solo los viernes 13.
Hay un giro más: si uno de los dos campos empieza por asterisco, como en */2, cron lo trata como no restringido para esta regla y deben cumplirse los dos campos. Por eso 0 0 */2 * 1 solo se ejecuta los lunes que caen en un día impar del mes. El generador de esta página avisa de los dos casos en su explicación.
Para ejecutar algo el primer lunes con el cron clásico, programa la tarea para los lunes y haz que el script termine sin hacer nada si el día del mes es mayor que 7. Quartz lo expresa directamente con 2#1.
Zonas horarias y horario de verano
Cron se ejecuta en la zona horaria de la máquina o del servicio que lo ejecuta. Muchos servidores y servicios en la nube usan UTC, las programaciones de GitHub Actions están siempre en UTC, y los CronJobs de Kubernetes usan la zona horaria del controlador salvo que indiques el campo timeZone. Algunos demonios de cron también leen una variable CRON_TZ en el crontab.
En las zonas con horario de verano, una noche al año no existe las 2:30 y otra noche la 1:30 ocurre dos veces. La mayoría de demonios de cron de Linux ejecutan las tareas de la hora saltada justo después del cambio y ejecutan las tareas de hora fija una sola vez en la hora repetida, mientras que las tareas que se ejecutan cada hora lo hacen en las dos. Otros programadores pueden saltarse la ejecución. Si una tarea debe ejecutarse exactamente una vez al día, prográmala fuera de la franja entre la 1:00 y las 3:00, o ejecuta el programador en UTC. La lista de ejecuciones del generador marca cada ejecución que cae en un cambio de hora.
Segundos, Quartz y Spring
Java y algunos programadores de tareas en JavaScript añaden un campo de segundos al principio, así que sus expresiones tienen seis campos: 0 */5 * * * * se ejecuta cada cinco minutos en el segundo 0. Quartz va más allá y cambia varias reglas, por eso una expresión clásica a menudo falla en él.
- Quartz tiene 6 o 7 campos: segundos, minuto, hora, día del mes, mes, día de la semana y un año opcional.
- Los días de la semana se numeran del 1 al 7 empezando por el domingo, así que MON es 2. Los nombres como MON-FRI evitan la confusión.
- Uno de los dos campos de día debe ser ?, que significa sin valor concreto. 0 0 9 ? * MON-FRI se ejecuta a las 9:00 de lunes a viernes.
- L significa último: L en el campo del día del mes es el último día del mes, 6L en el campo del día de la semana es el último viernes.
- W elige el día laborable más cercano: 15W se ejecuta el día laborable más próximo al 15, LW el último día laborable del mes.
- # elige el enésimo día de la semana: 6#3 es el tercer viernes del mes.
- @Scheduled de Spring también usa seis campos con los segundos primero, pero numera los días de la semana del 0 al 7 como el cron clásico y no exige ?.
Errores que conviene evitar
- Escribir * * * * * cuando quieres una vez al día. El primer campo es el minuto, así que esto se ejecuta 1440 veces al día.
- Esperar que */7 en el campo del día del mes signifique cada siete días. Significa los días 1, 8, 15, 22 y 29, y vuelve a empezar el día 1.
- Programar el día 31, 30 o 29. Los meses sin ese día se saltan, no se pasan al último día.
- Olvidar la zona horaria. 0 9 * * * en un servidor en UTC se ejecuta a las 9:00 UTC, que puede ser de noche donde están tus usuarios.
- Usar funciones de Quartz como L o ? en un crontab de Linux, o una expresión de cinco campos en Quartz. El generador convierte entre sintaxis cuando cambias de una a otra.