Compute the next executions of a cron expression

parses a cron expression and lists the next execution dates

What is a cron expression?

A cron expression is a short string that describes a recurrence in time. The format inherited from Unix fits in five fields separated by spaces: minute, hour, day of month, month and day of week. This syntax was born with Brian Kernighan's cron daemon in the 1970s, then generalised by Vixie cron (1987) adopted by all modern Linux and macOS distributions. Today, the same syntax can be found in most cloud schedulers (AWS EventBridge, GCP Cloud Scheduler, Azure Logic Apps) and CI/CD tools (GitHub Actions, GitLab CI, Jenkins).

┌──── minute (0-59)
│ ┌── hour (0-23)
│ │ ┌── day of month (1-31)
│ │ │ ┌── month (1-12 or JAN-DEC)
│ │ │ │ ┌── day of week (0-7 or SUN-SAT, 0 and 7 = Sunday)
│ │ │ │ │
* * * * *

A well-formed cron expression therefore defines a precise cron schedule: each field can be a fixed value, a range, a list, a step or an asterisk that matches everything. The compactness of the crontab expression is its strength, but it is also what makes a cron decoder indispensable to visually validate the intent. That is precisely the purpose of this cron converter: produce a readable cron explanation, plus the list of next executions.

Anatomy of a cron expression

The five fields share a common grammar. Here are the bounds accepted by each column of a standard crontab expression:

  • Minute: 0-59.
  • Hour: 0-23, 24h format.
  • Day of month: 1-31.
  • Month: 1-12 or the text abbreviations JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC.
  • Day of week: 0-7 where 0 and 7 both represent Sunday, or the abbreviations SUN, MON, TUE, WED, THU, FRI, SAT.

Special characters shared by the five fields:

  • *: any value, matches all allowed values of the field.
  • ,: discrete list, for example 1,15,30 in the minute field.
  • -: inclusive range, for example 9-17 for office hours.
  • /: step, for example */15 = every 15 units, or 0-30/5 = every 5 minutes between 0 and 30.

Quartz extensions (Java, AWS EventBridge, Spring): the grammar grows to 6 or 7 fields with a seconds column at the head (0-59) and sometimes a year column at the tail (1970-2099). Quartz also introduces ? (no specific value, to decouple day-of-month and day-of-week), L (last: last day of the month, or last Friday with 5L), W (nearest weekday) and # (nth day of the week of the month, for example 2#3 for the 3rd Monday). A Quartz expression is usually not compatible with a UNIX crontab, and vice versa: this is the main source of error when copying a cron expression from one platform to another.

# UNIX / Vixie cron (5 fields)
0 9 * * 1-5

# Quartz (6 fields with seconds)
0 0 9 ? * MON-FRI

# Quartz (7 fields with year)
0 0 9 ? * MON-FRI 2026

Why decode a cron expression?

Reading 0 0 * * * is quick. Reading */7 2-5 1,15 * 1-5 is much less so. When an expression goes beyond the trivial, the risk of misinterpretation rises and cron decoding becomes a review step in its own right.

  • Production debugging: understand why a task fired at 03:17 instead of 03:00, or identify an overlap between two jobs.
  • Code review: validate that a scheduler pushed in a pull request really does what the author claims, without having to memorise the semantics of every symbol.
  • Scheduler audit: review Linux cron jobs in /etc/crontab and /etc/cron.d/, Jenkins triggers, spec.schedule of Kubernetes CronJob, AWS EventBridge rules and GCP Cloud Scheduler jobs.
  • Legacy migration: take over a historical /etc/crontab without documentation and rebuild the task mapping before an infrastructure change.
  • Onboarding: allow a new developer to reread a crontab without having to learn every special character overnight.

How to use the cron decoder

How to decode a crontab expression with the tool:

  1. Paste your cron expression into the input field (5 fields separated by spaces).
  2. Indicate the number of next executions to compute.
  3. Click convert to launch the cron decode: the tool returns a human sentence explaining the trigger, plus the dated list of next executions.
  4. Visually check that the dates match your intent (time, day, frequency).
  5. Copy the output via the copy button to paste it into a ticket, a PR or technical documentation.

The tool does not just do syntactic parsing: it provides a natural-language cron explanation, which makes it both a cron decoder and a schedule validator.

Classic cron expression examples

The patterns below cover the essentials of cron schedules seen in production. They are all valid on Linux crontab, Kubernetes CronJob, GitHub Actions and most application schedulers.

Expression Human reading
* * * * * Every minute
0 * * * * Every hour on the hour
0 0 * * * Every day at midnight
0 0 * * 0 Every Sunday at midnight
*/15 * * * * Every 15 minutes
0 9 * * 1-5 9am Monday to Friday
0 0 1 * * The 1st of each month at midnight
0 0,12 * * * At midnight and noon every day
*/5 9-17 * * 1-5 Every 5 minutes during business hours
30 2 1,15 * * The 1st and 15th of the month at 2:30am

To run a cron task on a Linux server, edit the user crontab from the shell:

# edit the current user's crontab
$ crontab -e

# list existing tasks
$ crontab -l

# example line added: daily backup at 3am
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Example output of the cron converter for */5 * * * *:

2026-05-05 00:00:00
2026-05-05 00:05:00
2026-05-05 00:10:00
2026-05-05 00:15:00
2026-05-05 00:20:00
...

Frequently asked questions about the cron decoder

What is the difference between UNIX cron and Quartz?

UNIX/Vixie cron uses 5 fields (minute to day-of-week), without second-level precision, and has no native notion of "last day of the month". Quartz (Java, Spring, AWS EventBridge) adds a seconds column at the head, sometimes a year column at the tail, and several symbols (?, L, W, #) absent from the Linux crontab. A 6-field Quartz cron expression is therefore not directly portable to /etc/crontab, and vice versa. Our cron decoder targets the 5-field format, which covers most schedulers.

How do I run a cron task every 5 minutes?

With the step / on the minute field:

*/5 * * * * /usr/local/bin/check-health.sh

This crontab expression fires the script at minutes 0, 5, 10, 15... of every hour, every day. To limit to business hours Monday to Friday, add constraints on the hour and day-of-week fields: */5 9-17 * * 1-5.

What does the asterisk (*) mean in a cron expression?

The asterisk means any value: it matches all allowed values of the field. In 0 0 * * *, the three stars mean "any day of the month, any month, any day of the week". Combined with the first two fields set to 0, that gives "every day at midnight". The star can also be combined with a step: */15 in the minute field = every 15 minutes.

Does crontab have a time zone?

By default, the server's. On a Linux crontab, that is the system TZ (often UTC on VPSes and containers). GitHub Actions forces UTC. Kubernetes CronJob uses the controller's time zone, configurable via spec.timeZone since 1.27. AWS EventBridge evaluates expressions in UTC. Application schedulers (Symfony Scheduler, Quartz, Airflow) often allow setting a dedicated zone per task. When in doubt, check date on the target server and compare with the cron converter output.

Cron job vs the at command: which to pick?

cron runs a recurring task on a schedule. at runs a command once at a given moment. For a daily backup, log rotation or a regular API call, use cron. To defer a one-off operation ("re-run this deployment at 10pm tonight"), use at:

$ echo "/usr/local/bin/deploy.sh" | at 22:00
How do I test a cron expression without triggering it?

That is precisely the role of this cron converter: it computes the N next executions from the current instant, without starting any job. You see immediately whether your crontab expression fires at 03:00 as expected or at 03:17 by accident. To go further before installing the task, you can also test the script alone (bash -x script.sh) and check a crontab file's syntax with crontab -T file on the distributions that support it.

What happens if day-of-month and day-of-week are both set?

On Vixie cron (Linux), the rule is a logical OR: the job fires if either of the two fields matches. It is counter-intuitive and a source of bugs. Quartz uses an AND, which is why the ? symbol was introduced to explicitly signal "no constraint". As a general rule, set only one of the two fields.

Example request

curl -X POST https://cdrn.fr/api/v1/tools/cron-converter/execute \
  -H "Content-Type: application/json" \
  -d '{"cron":"...","number_next_date":1}'

Input schema

Field Type Required Default
cron string
number_next_date integer

Endpoints

  • GET https://cdrn.fr/api/v1/tools - lists every available tool
  • GET https://cdrn.fr/api/v1/tools/cron-converter - returns the schema for this tool
  • POST https://cdrn.fr/api/v1/tools/cron-converter/execute - runs this tool with a JSON payload