Cron expression builder and explainer
Build a cron expression from fields, read it back in plain English, and preview the next five run times.
What this does
A cron expression is five space-separated fields — minute (0–59), hour
(0–23), day of month (1–31), month (1–12), day of week (0–7, where 0 and 7
are both Sunday) — each of which can be a number, a list
(1,15), a range (9-17), a step
(*/15), or *. This tool renders the expression as
an English sentence using cronstrue
and computes the next five fire times with
cron-parser in the
time zone you select.
It's a static page with the logic bundled in — no request is made when you type.
When you'd use it
- Writing a schedule for a cron job, a CI pipeline, a serverless function, or a Kubernetes CronJob and wanting to confirm it means what you think.
- Reading an unfamiliar cron line in someone else's config.
- Checking when a job will next run, and whether a change shifts that.
- Debugging a job that "didn't run" — often a day-of-week vs day-of-month interaction or a step value that doesn't divide evenly.
Worked example
The default expression:
*/15 9-17 * * 1-5
reads as "every 15 minutes, between 09:00 and 17:59, Monday through
Friday". Note it fires at 17:00, 17:15, 17:30, and 17:45 but not 18:00,
because the hour range 9-17 includes hour 17 in full. If you
wanted it to stop at 17:00 exactly, the expression is
0,15,30,45 9-16 * * 1-5 plus a separate 0 17 * * 1-5,
or simply */15 9-17 * * 1-5 accepted as "through the 5 o'clock
hour". Change the last field to 1-5 → 6,0 and the
next-runs list jumps to Saturday and Sunday.
Limits and gotchas
- 5 fields only. No seconds field, no
@daily-style macros, noL/W/#Quartz extensions. - OR semantics for the two day fields. Restricting both day-of-month and day-of-week broadens the schedule rather than narrowing it.
- Steps start from the minimum.
*/40in minutes is 0 and 40 only, then it resets at the top of the hour. - DST. Run times near a daylight-saving change can be skipped or doubled depending on the running system's rules.
- The runner's clock wins. This tool's prediction assumes the schedule is interpreted in the zone you pick; verify what your platform actually uses.
Frequently asked questions
- Why does my "day of month" and "day of week" both being set behave oddly?
- In standard cron, when both field 3 (day of month) and field 5 (day of week) are restricted (neither is
*), the job runs when either matches, not both. So0 0 13 * 5means "midnight on the 13th, and also every Friday", not "Friday the 13th". To get a single condition, leave the other field as*. - What does */15 actually mean?
- A step value.
*/15in the minute field means minutes 0, 15, 30, 45. It is "every 15 starting from the field's minimum", not "15 minutes after whenever the job last ran".*/20in the hour field gives 0 and 20 — because there is no hour 40 — which is a common surprise. - Is the schedule in UTC or my local time?
- That depends on the system running it. Linux
cronuses the machine's local time zone; many managed schedulers default to UTC. This tool lets you pick, and shows each run in both the chosen zone and UTC so you can match it to your platform. Around daylight-saving transitions, a job scheduled for a skipped or repeated local hour may run zero or two times. - Does this support seconds or the @hourly / @daily shortcuts?
- No. This tool handles the classic 5-field format (minute, hour, day-of-month, month, day-of-week). Six-field expressions with a leading seconds field (used by Quartz, some Kubernetes tooling, and node-cron) and named shortcuts like
@dailyare not parsed here.