Crontab Parser — Explain cron expressions
Translate crontab expressions (5-field or 6-field) into plain English and preview the next 10 run times. Works for Linux cron, Kubernetes CronJobs and CI.
Crontab Syntax
┌───────────── minute (0 - 59) │ ┌───────────── hour (0 - 23) │ │ ┌───────────── day of month (1 - 31) │ │ │ ┌───────────── month (1 - 12) │ │ │ │ ┌───────────── day of week (0 - 6) (0=Sun) │ │ │ │ │ │ │ │ │ │ * * * * *
*— every minute/hour/day/month,— list:1,3,5= 1, 3, and 5-— range:9-17= every hour from 9 to 17/— step:*/15= every 15 minutes;0-59/5= every 5 minutes@yearly/@annually— 0 0 1 1 *@monthly— 0 0 1 * *@weekly— 0 0 * * 0@daily/@midnight— 0 0 * * *@hourly— 0 * * * *
How it works
Type any crontab expression — the parser expands each field into a set of integer values, then converts that set into human-readable English ("At 02:00 every day" / "Every 15 minutes between 09:00 and 17:00 on weekdays"). It then walks forward from now to list the next ten concrete dates and times the scheduler would fire. Kubernetes CronJobs use the same syntax plus an optional leading seconds field; toggle the switch to parse 6-field expressions.
The five-field grammar, field by field
Every field expands independently into a sorted set of integers, and a minute fires when the time fields match and the day rule below is satisfied. Expansion runs a small pipeline per comma-separated token: split off a `/step`, resolve the base — `*` or `?` becomes the field's whole range, `a-b` becomes that range, and a bare value becomes either that single value or, when a step is present, `value-max` — then walk it by `step`. So `*/15` and `0/15` both yield 0, 15, 30, 45, matching Vixie cron, and a field that resolves to nothing is reported as an error rather than silently never firing.
Names resolve per range endpoint, as full names or as prefixes of at least three characters, so `monday`, `mon` and `mon-fri` all work in the weekday field and `january`, `jan` and `jan-mar` work in the month field. Values outside the field's range are dropped rather than kept, so minute `99` is an error instead of a value that can never match.
Time zones and the six-field variant
The walk starts at the current local minute and steps forward one minute at a time, so every listed time is browser-local wall clock. Each row prints twice — through `toLocaleString()` and as a UTC instant — because a bare local timestamp tells you nothing about the offset a scheduler will really use. Across a DST change the two columns diverge: the UTC instants stay evenly spaced while the local labels jump, and a job pinned to 02:30 either runs once that night or not at all.
Toggling the seconds field simply prepends `0 `, so `0 2 * * *` becomes `0 0 2 * * *`. The seconds set is built and then never consulted: the next-run walk still advances a minute at a time, so every preview row lands on `:00` seconds regardless of what the first field says. `@reboot` maps to `0 0 0 1 1 0` here, and that is read as six fields — midnight on 1 January, annually — not as the boot-time trigger it means elsewhere.
Where cron implementations disagree
Field combination is where implementations diverge most, and this tool follows the Vixie rule: when day-of-month and day-of-week are both restricted the two are ORed, so `0 0 13 * 5` fires on the 13th and on every Friday. When only one of them is restricted the other acts as a filter, so `0 0 * * 5` is every Friday and `0 0 13 * *` is every 13th. Some schedulers intersect instead, which turns `0 0 13 * 5` into the much rarer "13th that is also a Friday" — check your runtime if that distinction matters.
Kubernetes CronJob controllers are stricter again: `.spec.schedule` takes five fields, rejects `@daily` and the other shorthands, and evaluates in the controller's own UTC, so a manifest built from a browser-local preview can fire at a different wall-clock hour than the one shown here. Seven-field input is truncated to the first five.
Next steps
- Crontab Explainer— simpler 5-field syntax
Frequently Asked Questions
How do I parse a cron expression?
What cron format is supported?
Is my data sent to a server?
Do I need an account or API key?
Can I use these tools offline?
All processing happens in your browser. No uploads, no tracking, no servers. Your API keys, configs, and private payloads stay private — 100% client-side.