Zum Hauptinhalt springen

Syntax von Cron-Ausdrücken

Ein Cron-Ausdruck besteht aus fünf Feldern – Minute, Stunde, Tag des Monats, Monat, Tag der Woche –, die jeweils *, eine Zahl, einen Bereich wie 1-5, einen Schritt wie */15 oder eine Liste wie 1,3,5 enthalten. Alle Felder greifen gemeinsam – mit einer Ausnahme, der klassischen Falle: Beschränken Sie Tag des Monats und Tag der Woche beide, verknüpft cron sie mit ODER, nicht mit UND. Die Ausführungszeit richtet sich nach der Uhr des Servers.

Nur lokal
Direkt zum Tool? Cron-Ausdruck prüfen öffnenEinen Zeitplan lesen und sehen, wann er tatsächlich läuftTool öffnen

Syntax von Cron-Ausdrücken erklärt

Cron ist seit den 1970ern der Unix-Scheduler, und seine Grammatik hat sich kaum bewegt: fünf kleine Felder, die zusammen die Frage „wann läuft das“ beantworten. Der Syntax begegnet Ihnen in Crontabs, CI-Systemen, Kubernetes CronJobs, Datenbank-Wartungsplänen und in der Hälfte der Scheduler im Internet – eine Syntax, alt genug, um wählen zu dürfen, und immer noch vorne, weil sie in eine Zeile passt.

Die Grammatik ist einfach; die Ränder sind es nicht. Jedes Feld wird mit den anderen geschnitten, genau eine Ausnahme gibt es – Tag des Monats versus Tag der Woche –, und sie tut das Gegenteil dessen, was die Intuition verlangt. Für den Sonntag stehen sowohl 0 als auch 7. Die freundlichen @daily-Kürzel sind Erweiterungen, kein Teil des Standards. Und ein Zeitzonenfeld fehlt der Syntax an jeder Stelle, sodass jeder Ausdruck stillschweigend die Uhr erbt, die sein Host gerade verwendet.

Dieser Leitfaden geht die fünf Felder, die Operatoren, die Tagesfeld-Falle, die Kürzel und die Zeitzonen-Realität durch und endet damit, wie Sie einen Ausdruck testen, bevor Sie einen Produktionsjob darauf verwetten. Der hier verlinkte Tester läuft vollständig in Ihrem Browser – der Ausdruck verlässt den Tab nie.

Am schnellsten sitzen diese Regeln, wenn Sie sie absichtlich brechen und zusehen, wie ein Parser reagiert – halten Sie also den Cron-Expression-Tester im nächsten Tab offen: Er beschreibt, was Ihr Ausdruck bedeutet, und listet die nächsten Laufzeiten auf, lokal berechnet.

Moderne Zeitpläne leben meist in Deployment-Dateien statt in Crontabs; wird Ihr Ausdruck also in einer Pipeline-Definition ausgeliefert, der YAML-Grundlagen-Leitfaden behandelt die Einrückungs-, Anführungs- und Typregeln, denen diese Datei folgt.

Die fünf Felder

Ein standardmäßiger Cron-Ausdruck besteht aus genau fünf durch Leerzeichen getrennten Feldern in fester Reihenfolge: Minute, Stunde, Tag des Monats, Monat, Tag der Woche. Ein Job feuert, wenn jedes Feld auf die aktuelle Zeit passt – die Felder werden mit UND verknüpft. Schreiben Sie 30 4 * * * und der Job läuft täglich um 04:30; jedes Feld muss übereinstimmen, damit der Moment zählt.

Jedes Feld akzeptiert Zahlen aus seinem Bereich, und die Monats- und Wochentagsfelder nehmen auch Namen – JAN-DEC und SUN-SAT –, die manche Scheduler groß- und kleinschreibungsunabhängig akzeptieren. Die Bereiche lohnen sich zu merken, denn zwei von ihnen beginnen an unerwarteter Stelle: Monate zählen ab 1, Wochentage ab 0. Alles Weitere an der Cron-Syntax sind Operatoren, die über diese Felder gelegt sind.

FeldPositionErlaubte WerteNamen erlaubt
Minute1.0-59–
Stunde2.0-23–
Tag des Monats3.1-31–
Monat4.1-12JAN-DEC
Tag der Woche5.0-7 (0 und 7 sind beide Sonntag)SUN-SAT

Bereiche, Schritte und Listen

Drei Operatoren erledigen in echten Ausdrücken die meiste Arbeit. Ein Bereich, 1-5, passt auf jeden Wert zwischen seinen Endpunkten, einschließlich. Ein Schritt, nach einem Schrägstrich notiert, passt auf jeden N-ten Wert des Felds oder Bereichs vor ihm – */15 im Minutenfeld bedeutet 0, 15, 30, 45, und 9-17/2 im Stundenfeld bedeutet jede zweite Stunde von 9 bis 17. Eine Liste, 1,3,5, passt auf genau die genannten Werte, und die Operatoren lassen sich kombinieren: 1-5,10 und 0-30/5 sind beide legal.

Zwei Gewohnheiten halten Schritte ehrlich. Erstens enthält */N immer das Minimum des Felds – */15 trifft also Minute 0, weshalb ganze Scharen von */15-Jobs zur vollen Stunde gemeinsam aufwachen. Zweitens ist ein Schritt über einen expliziten Bereich oft klarer als eine Liste: 0-59/10 liest sich als „alle zehn Minuten“, 0,10,20,30,40,50 eher nicht.

AusdruckLiest sich als
0 9 * * 1-509:00, Montag bis Freitag
*/15 * * * *Alle 15 Minuten
0 0 1 * *Mitternacht am 1. jedes Monats
30 4 1,15 * SUN04:30 am 1., am 15. und an jedem Sonntag
0 22 * * 1-522:00 an Wochentagen

Ein Ausdruck, getestet

30 9 * * 1-5

Was der Tester sagt

At 09:30, on Monday through Friday.
Next runs (UTC):
  Mon 2026-09-21 09:30
  Tue 2026-09-22 09:30

Die Falle: Tag des Monats gegen Tag der Woche

Jedes Feldpaar wird geschnitten – außer Tag des Monats und Tag der Woche, die cron mit ODER verknüpft, sobald beide eingeschränkt sind. Die klassische Überraschung: 0 0 13 * 5 bedeutet nicht „Freitag, der 13.“. Es bedeutet Mitternacht am 13. des Monats oder Mitternacht an irgendeinem Freitag – ein Job, der in manchen Wochen zweimal läuft und an Daten, die Sie nie beabsichtigt haben. Ist eines der beiden Tagesfelder *, kehrt das normale UND-Verhalten zurück, und nur das andere zählt.

Die ODER-Regel ist kein Fehler; sie steht in der Dokumentation von POSIX und Vixie cron, und sie überlebt, weil sie die beiden Tagesfelder verschiedenen Herren dienen lässt – ein monatlicher Job am 1. kann im selben Feldpaar neben einem wöchentlichen Job am Sonntag existieren. Sie unterläuft aber jede Intuition, deshalb die defensiven Gewohnheiten: Nie beide Felder einschränken, solange Sie die ODERs nicht durchgezählt haben, und wenn Sie wirklich „Freitag, den 13.“ brauchen, planen Sie täglich und prüfen das Datum im Befehl selbst.

Der Sonntag ist 0 und 7, und die Kürzel sind Erweiterungen

Der Wochentag nimmt für den Sonntag sowohl 0 als auch 7 an – in Vixie cron, der Implementierung, von der die meisten Systeme abstammen –, und 7 wird beim Einlesen auf 0 gefaltet. Das ist eine Höflichkeit für Bereiche – SUN-SAT lässt sich als 0-6 oder 1-7 schreiben –, aber auch eine Bruchstelle, was die Portabilität angeht: Manche anderen Implementierungen weisen 7 grundsätzlich zurück, und ein paar Eigenheiten beim Parsen machen 7 in Listen riskant. 0 für den Sonntag zu schreiben ist die portable Wahl.

Die @-Kürzel – @reboot, @yearly, @annually, @monthly, @weekly, @daily, @midnight und @hourly – sind ebenfalls Vixie-Erweiterungen, kein Teil der POSIX-Grammatik. Unterstützt werden sie trotzdem fast überall, wo sich etwas cron-kompatibel nennt, was sie in der Praxis unbedenklich macht – und es lohnt sich weiterhin, sie gedanklich aufzulösen: @daily ist 0 0 * * *, Mitternacht an jedem Tag, und @reboot bedeutet einmalig beim Start des Daemons, was nach einer Neuplanung früher oder später eintreten kann als erwartet.

KürzelLöst sich auf zuBedeutung
@reboot–Einmalig, wenn der Cron-Daemon startet
@yearly / @annually0 0 1 1 *Mitternacht, 1. Januar
@monthly0 0 1 * *Mitternacht am 1. jedes Monats
@weekly0 0 * * 0Mitternacht an jedem Sonntag
@daily / @midnight0 0 * * *Mitternacht an jedem Tag
@hourly0 * * * *Zur vollen Stunde

Das Zeitzonenfeld, das nicht existiert

Cron hat kein Zeitzonenfeld. Ein Ausdruck wird gegen die Uhr des Daemons ausgewertet – die lokale Systemzeit des Servers –, sodass dieselbe Crontab auf Maschinen in verschiedenen Zonen unterschiedliche Zeiten bedeutet und ein Umzug eines Jobs von einem Tokyo-Host zu einem in Frankfurt den Zeitplan stillschweigend verschiebt. Container verschärfen das: Die meisten laufen in UTC, ganz gleich, wo ihre Betreiber sitzen, sodass „wann es läuft“ und „wann ich es meinte“ um einen Offset auseinanderdriften, den niemand angekündigt hat.

Die Sommerzeit bringt in jeder Lokalzeit-Zone eigene Gefahren mit: Ein Job um 02:30 existiert in der Nacht, in der die Uhren vorgestellt werden, nicht, und ein Job um 01:30 läuft in der Nacht, in der sie zurückgestellt werden, zweimal. Manche Implementierungen akzeptieren nicht portable Zusätze – eine TZ- oder CRON_TZ-Zeile in der Crontab oder eine Zeitzone in der eigenen Konfiguration des Schedulers –, aber die Unterstützung variiert, und Portabilität endet dort, wo diese Zeilen beginnen. Die ehrliche Praxis: Wissen Sie, mit welcher Uhr Ihr Ausdruck rechnet; der Tester dieser Website rechnet alles in UTC und sagt das neben jedem Ergebnis.

Einen Ausdruck testen, bevor er ausgeliefert wird

Manche Ausdrücke sind legal und unerfüllbar – 0 0 31 2 * verlangt den 31. Februar, und keine naive Suchschleife über Daten findet ihn je; deshalb begrenzt ein echter Tester seine Suche auf Jahre und meldet stattdessen einen nie feuernenden Zeitplan, statt sich aufzuhängen. Andere Ausdrücke sind legal und nur nicht das, was Sie meinten; die 13.-oder-Freitag-Falle erzeugt Zeitpläne, die tagelang richtig aussehen, bevor sie Sie überraschen.

Der Arbeitsablauf, der beides abfängt: Schreiben Sie den Ausdruck, lassen Sie ihn sich in Worten zurückbeschreiben und sehen Sie sich die nächsten konkreten Laufzeiten an. Eine Beschreibung sagt, was ein Parser glaubt, dass Sie geschrieben haben; konkrete Zeitstempel zeigen, wo er tatsächlich feuert. Der Tester auf dieser Seite macht beides – Fünf-Felder-Standardsyntax plus sechs- und siebenfeldrige Varianten im Quartz-Stil – vollständig in Ihrem Browser, sodass ein Ausdruck mit internen Jobnamen oder Hostnamen den Tab nie verlässt.

Häufig gestellte Fragen

Lädt der Cron-Tester meine Ausdrücke oder Jobnamen hoch?

Nein. Parsen, Beschreiben und die Berechnung der nächsten Läufe geschehen allesamt in JavaScript innerhalb Ihres Browser-Tabs; der Ausdruck verlässt Ihren Rechner nie. Prüfen Sie es in den DevTools: Öffnen Sie das Netzwerk-Panel, werten Sie einen Ausdruck aus und sehen Sie zu, wie die Anfrageliste leer bleibt. Die Content-Security-Policy der Website verbietet auch Seitenskripten ausgehende Verbindungen.

Warum bedeutet 0 0 13 * 5 nicht „Freitag, der 13.“?

Weil cron die Tagesfelder mit ODER verknüpft, sobald beide eingeschränkt sind: Dieser Zeitplan feuert um Mitternacht am 13. des Monats oder an jedem Freitag, je nachdem, was zuerst kommt – nicht am Freitag, den 13. Das ist definiertes Verhalten, in POSIX wie in Vixie cron. Um die tatsächliche Koinzidenz zu erwischen, planen Sie den Job täglich und prüfen das Datum in dem Befehl, den er ausführt.

Ist 7 ein gültiger Wochentagswert?

In Vixie cron und seinen Nachkommen ja – sowohl 0 als auch 7 bedeuten Sonntag, wobei 7 beim Einlesen auf 0 gefaltet wird. Aber es ist die am wenigsten portable Ecke der Syntax: Manche Implementierungen weisen 7 grundsätzlich zurück, und es verhält sich dort in Listen und Bereichen eigenwillig. 0 für den Sonntag zu schreiben kostet nichts und vermeidet den Streit vollständig.

In welcher Zeitzone läuft ein Cron-Ausdruck?

Mit der Uhr, die der Daemon verwendet – der lokalen Systemzeit des Servers, denn cron hat kein Zeitzonenfeld. Container laufen meist in UTC. Manche Implementierungen akzeptieren eine TZ- oder CRON_TZ-Zeile in der Crontab, aber das ist nicht portabel, und Lokalzeit-Zonen bringen Sommerzeit-Eigenheiten mit, bei denen 02:30-Jobs eine Nacht auslassen und 01:30-Jobs zweimal laufen. Kennen Sie die Uhr, bevor Sie dem Zeitplan vertrauen.

Sind @daily, @weekly und @reboot Standard-Cron?

Es sind Vixie-cron-Erweiterungen statt POSIX, aber die Unterstützung ist nahezu universell, wo sich etwas cron nennt. Lohnend zu wissen, worin sie sich auflösen: @daily ist 0 0 * * *, @weekly ist 0 0 * * 0, und @reboot feuert, wenn der Daemon startet – nach einer Neuplanung der Maschine oder einem Container-Neustart also immer genau dann, wenn es passiert, nicht zu einer festen Zeit.

Warum läuft mein Job nicht am letzten Tag des Monats?

Cron hat keine Syntax für den „letzten Tag“ – der Tag des Monats endet bei 31, und 31 passt nur in sieben Monaten des Jahres. Der übliche Workaround ist ein kleiner Shell-Test: täglich um Mitternacht einplanen und nur laufen lassen, wenn morgen der 1. ist. Scheduler mit reicheren Kalendern (systemd-Timer, Quartz mit seinem L-Flag) drücken das nativ aus; POSIX cron tut es mit Absicht nicht.