Compute the next executions of a cron expression
- Dashboard
- Documentation
- API
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-12or the text abbreviationsJAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC. - Day of week:
0-7where0and7both represent Sunday, or the abbreviationsSUN,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 example1,15,30in the minute field.-: inclusive range, for example9-17for office hours./: step, for example*/15= every 15 units, or0-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/crontaband/etc/cron.d/, Jenkins triggers,spec.scheduleof Kubernetes CronJob, AWS EventBridge rules and GCP Cloud Scheduler jobs. - Legacy migration: take over a historical
/etc/crontabwithout 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:
- Paste your cron expression into the input field (5 fields separated by spaces).
- Indicate the number of next executions to compute.
- Click convert to launch the cron decode: the tool returns a human sentence explaining the trigger, plus the dated list of next executions.
- Visually check that the dates match your intent (time, day, frequency).
- 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 toolGET https://cdrn.fr/api/v1/tools/cron-converter- returns the schema for this toolPOST https://cdrn.fr/api/v1/tools/cron-converter/execute- runs this tool with a JSON payload