Expressions cron : champs, pas et fuseaux horaires

Mis à jour :

Cron est le planificateur qui lance des commandes à heures fixes sur les systèmes de type Unix, et son format à cinq champs s’est répandu bien au-delà : GitHub Actions, Kubernetes et de nombreux panneaux d’hébergement utilisent la même notation. Une ligne comme 30 2 * * 1 se lit « à 02:30 tous les lundis ». L’essentiel du format est simple ; quelques règles ne le sont pas, et ce sont elles qui expliquent les tâches lancées à la mauvaise heure, deux fois ou jamais. Ce guide suit la norme POSIX et cronie, un cron très répandu sous Linux, et signale où les autres planificateurs diffèrent.

Les cinq champs

Une ligne de crontab comporte cinq champs horaires séparés par des espaces, suivis de la commande. La tâche part à chaque minute qui les satisfait tous, avec une exception pour les deux champs de jour, expliquée plus bas. La norme numérote les jours de la semaine de 0 à 6, 0 étant le dimanche ; cronie et la plupart des cron Linux acceptent aussi 7 pour le dimanche, ainsi que des noms anglais de trois lettres comme mon ou jan, en majuscules ou minuscules.

ChampValeursExempleSignifie
Minute0–5930à la minute 30
Heure0–232de 02:00 à 02:59
Jour du mois1–311,15le 1er et le 15
Mois1–12 ou jan–dec*tous les mois
Jour de la semaine0–7 ou sun–sat (0 et 7 sont le dimanche)1-5du lundi au vendredi

Un astérisque désigne toutes les valeurs du champ. Les heures suivent l’horloge de 24 heures : 9 correspond à 09:00 et 21 à 21:00.

Listes, plages et pas

Un champ peut contenir une liste (1,15), une plage (9-17) ou un pas. Le pas découpe une plage : 0-30/10 dans le champ des minutes désigne les minutes 0, 10, 20 et 30, et */15 parcourt toutes les valeurs à partir de la première, soit les minutes 0, 15, 30 et 45. Les pas se comptent depuis le début de la plage et repartent à chaque nouvelle heure, journée ou mois ; ils ne se prolongent pas depuis le précédent.

Dans le champ des minutes, seuls les pas qui divisent 60 exactement (1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30) donnent des intervalles égaux. Toutes les 90 minutes, il faut deux lignes : 0 0-21/3 * * * part à 00:00, 03:00 … 21:00, et 30 1-22/3 * * * à 01:30, 04:30 … 22:30.

cronie accepte aussi des raccourcis : @hourly, @daily (0 0 * * *), @weekly (0 0 * * 0), @monthly (0 0 1 * *), @yearly ou @annually (0 0 1 1 *) et @reboot, qui s’exécute une fois au démarrage. Ils ne font pas partie de la norme : GitHub Actions, par exemple, ne les accepte pas.

Générateur Cron

Jour du mois ou jour de la semaine

Quand les champs du jour du mois et du jour de la semaine contiennent autre chose qu’un astérisque, la norme dit qu’un jour convient si l’un ou l’autre correspond, pas les deux. 0 9 13 * 5 part donc à 09:00 tous les 13 du mois et tous les vendredis, pas seulement le vendredi 13. En novembre 2026, ce sont les 6, 13 (un vendredi, lancé une seule fois), 20 et 27.

Pour combiner les deux, planifiez un champ et laissez la commande vérifier l’autre. Dans une crontab, un % dans la commande devient un saut de ligne ; il faut donc l’écrire \% :

Fuseaux horaires et heure d’été

Cron lit la planification dans le fuseau horaire de la machine ou du service qui l’exécute, souvent UTC sur les serveurs et les plateformes hébergées. 0 9 * * * sur un serveur en UTC part à 10:00 ou 11:00 à Paris, Berlin, Madrid ou Rome selon la saison, et à 09:00 ou 10:00 à Lisbonne et Londres. Le Brésil n’a pas d’heure d’été : à São Paulo, c’est toujours 06:00. cronie permet à une crontab de fixer son propre fuseau avec la variable CRON_TZ ; GitHub Actions accepte une clé timezone à côté de cron ; Kubernetes dispose du champ .spec.timeZone, stable depuis la version 1.27, et refuse CRON_TZ ou TZ écrits dans la planification.

L’heure d’été fait disparaître ou se répéter certaines heures locales. Le 29 mars 2026, les horloges de Paris, Berlin, Madrid et Rome passent de 02:00 à 03:00 : 30 2 * * * désigne alors une heure qui n’existe pas ; le 25 octobre 2026, l’heure de 02:00 à 03:00 se produit deux fois. À Lisbonne et à Londres, c’est l’heure de 01:00 à 02:00.

PlanificateurTâche dans l’heure sautéeTâche dans l’heure répétée
cronie (changements de moins de 3 heures, tâches à heure fixe ou moins fréquentes qu’une fois par heure)exécutée juste après le changementexécutée une fois
GitHub Actions (avec timezone)reportée à l’heure valide suivante : 02:30 devient 03:00non précisé
AWS EventBridge Scheduler (avec un fuseau)ignoréeexécutée une fois
Planifications en UTCaucun effetaucun effet

cronie planifie normalement les tâches lancées plus d’une fois par heure, et son manuel crontab prévient de façon générale que les heures manquantes ne correspondent jamais et que les heures répétées peuvent lancer deux fois : le comportement varie donc d’un cron à l’autre. Le plus sûr est de garder la planification en UTC, ou d’éviter les heures entre 01:00 et 03:00 locales pour les tâches qui doivent tourner exactement une fois par jour.

L’environnement d’une tâche

Une tâche cron ne reçoit pas l’environnement de votre terminal. La norme exécute la commande avec sh et un jeu minimal de variables (HOME, LOGNAME, PATH et SHELL) : une commande qui fonctionne quand vous la tapez peut échouer sous cron parce qu’un programme n’est pas dans le PATH ou qu’une variable manque. Utilisez des chemins complets, ou définissez PATH en tête de la crontab.

Tout ce que la commande affiche est envoyé par courriel au propriétaire de la crontab ; cronie l’envoie plutôt à l’adresse de MAILTO, et n’envoie rien si MAILTO est vide. Sur un serveur sans messagerie configurée, cette sortie se perd facilement : envoyez-la plutôt dans un fichier journal.

Cron lance chaque exécution à l’heure prévue, que la précédente soit terminée ou non : une tâche qui dure parfois plus longtemps que son intervalle peut donc tourner deux fois en même temps. flock, de util-linux, garde un fichier de verrou pendant la commande ; avec -n, il abandonne aussitôt, avec le code de sortie 1, si le verrou est pris. Kubernetes intègre le même choix : concurrencyPolicy vaut Allow par défaut, et peut valoir Forbid (ignorer la nouvelle exécution) ou Replace (arrêter l’ancienne).

La même planification sur d’autres plateformes

Le format à cinq champs n’est pas universel. Certains planificateurs ajoutent les secondes ou une année, d’autres exigent un point d’interrogation dans l’un des deux champs de jour parce qu’ils ne gèrent pas la règle de l’un ou l’autre, et d’autres numérotent les jours de la semaine à partir de 1. « Chaque jour ouvré à 09:00 » dans chacun :

PlanificateurExpressionRemarques
Cron Linux (cronie)0 9 * * 1-5Fuseau de la machine, ou CRON_TZ.
GitHub Actions0 9 * * 1-5UTC sauf si timezone est indiqué ; au plus une fois toutes les 5 minutes ; pas de raccourcis en @.
Kubernetes CronJob0 9 * * 1-5Fuseau du contrôleur, ou .spec.timeZone.
AWS EventBridgecron(0 9 ? * MON-FRI *)Six champs avec l’année ; ? dans un champ de jour ; les jours 1–7 commencent le dimanche ; les règles planifiées sont en UTC.
Quartz (Java)0 0 9 ? * MON-FRISecondes en premier, année facultative ; ? dans un champ de jour ; les jours 1–7 commencent le dimanche.
Minuteur systemdOnCalendar=Mon..Fri *-*-* 09:00:00Le jour de la semaine et la date doivent correspondre tous les deux ; *-*~01 est le dernier jour du mois.

Quand vous copiez une planification d’un système à l’autre, vérifiez le nombre de champs et la numérotation des jours de la semaine : 1 est le lundi dans cron, mais le dimanche dans Quartz et EventBridge.

Pourquoi une tâche n’est pas partie

Avant de vous fier à une planification, relisez-la champ par champ et, sous Linux, vérifiez les prochaines exécutions : systemd-analyze calendar les affiche pour une expression de minuteur.

Questions fréquentes

Le dimanche, c’est 0 ou 7 ?

Les deux, dans cronie et la plupart des cron Linux. La norme POSIX ne définit que 0 à 6, 0 étant le dimanche : 0 est donc le choix portable.

Cron peut-il lancer une tâche toutes les 30 secondes ?

Non : la plus petite unité est la minute. Les planificateurs avec un champ des secondes, comme Quartz, le peuvent ; sous Linux, un minuteur systemd aussi.

Comment lancer une tâche toutes les 90 minutes ?

Avec deux lignes : 0 0-21/3 * * * et 30 1-22/3 * * *. Ensemble, elles partent toutes les heures et demie, de 00:00 à 22:30.

Que signifie 0 0 * * 0 ?

Minuit au début de chaque dimanche. C’est l’équivalent de @weekly dans cronie.

Pourquoi ma tâche part-elle des jours que je n’ai pas choisis ?

Sans doute parce que les deux champs de jour sont fixés. Le cron standard lance la tâche quand le jour du mois ou le jour de la semaine correspond.

Références

  1. The Open Group Base Specifications (POSIX.1-2024) — crontab
  2. cronie — crontab(5): tables for driving cron
  3. cronie — cron(8): daylight saving time and other time changes
  4. util-linux — flock(1)
  5. GitHub Docs — Events that trigger workflows: schedule
  6. Kubernetes documentation — CronJob
  7. Amazon EventBridge — Cron expressions for scheduled rules
  8. Amazon EventBridge Scheduler — Schedule types (time zones and daylight saving)
  9. Quartz Scheduler — CronTrigger tutorial
  10. systemd — systemd.timer(5) and systemd.time(7): calendar events

Guides associés