Cron Expression Generator
Pick minutes, hours and days visually and get a correct cron expression with plain-English read-back — entirely on this device.
30 2 * * *Plain EnglishAt 02:30
| Run | Local time | DST |
|---|---|---|
| 1 | — | — |
| 2 | — | — |
| 3 | — | — |
30 2 * * * /usr/local/bin/job.sh
schedule: "30 2 * * *"
on:
schedule:
- cron: "30 2 * * *"Press ? for shortcuts
Do it offline:$ crontab -e
How to use it
- Pick a mode for each field — every, every N, specific values or range — and the expression assembles with each choice.
- Or paste an expression: the controls sync to whatever parses, and errors point at the exact field that failed.
- Confirm the schedule from the plain-English sentence and the next three runs.
- Copy or download the expression, take a deployment snippet, or share the state as a link.
Pick minutes, hours, days, months and weekdays from labeled controls and the matching cron expression assembles itself — validated by the same parser that checks anything you type, so the builder and the text field can never disagree. A plain-English read-back confirms the schedule, a preview shows the next three runs, and copy-ready crontab, Kubernetes and GitHub Actions snippets update as you build.
How it works
A classic crontab line is five space-separated fields — minute, hour, day of month, month, day of week — each taking a wildcard (*), a value (30), a list (1,4,7,10), a range (9-17) or a step (*/15, 8-17/2). JAN or MON in any case normalize to numbers; @daily-style macros expand to five fields first.
The crontab(5) day rule is the part worth memorizing: with day of month and day of week both restricted, a run happens when either side matches. The builder renders your selections to field text and runs it through the shared parser — the exact path typed input takes — so the sentence read back is what the daemon will do.
Examples
Every day at 02:3030 2 * * *Two selections — minute 30, hour 2 — and the read-back answers “At 02:30”. Cron has no time-zone field: this fires at 02:30 on the daemon's clock, so the preview names the zone it computes in.
Every 15 minutes, business hours, weekdays*/15 9-17 * * 1-5Reads back as “Every 15 minutes, between 09:00 and 17:59, Monday through Friday” — the 17:59 is honest: hour 17 covers the whole hour, so the day's last run lands at 17:45.
First day of each quarter, midnight0 0 1 1,4,7,10 *Four month checkboxes plus day 1 become a comma list, read back as “At 00:00, on day 1 of the month, only in January, April, July, and October”.
Day 1 and Mondays — both restricted0 9 1 * 1Restricting both day fields trips the live warning “Day-of-month and day-of-week are both restricted — cron runs when EITHER matches, which surprises most people.” This fires every 1st and every Monday, not only on Mondays that fall on the 1st.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Two day fields make an either-or
Restrict day of month and day of week together and the job fires when either matches — a warning chip appears the moment your selections form that pair.
Steps ride on ranges
8-17/2 means 8 through 17, every second value — 8, 10, 12, 14, 16. Pasting it lands back in range mode, step filled in.
Five wildcards are legal — and loud
* * * * * validates, so the builder answers with the note “This expression runs every minute — 1,440 times a day.” If that is intended, copy away.
Macros arrive as fields
@daily and friends normalize to five fields with a chip naming the expansion; @reboot is refused honestly — boot time is not a calendar schedule.
The last day of the month cannot be said here
28-31 fires on all four dates in longer months — a different schedule. Quartz’s L covers the intent, so the last-day control offers that hand-off instead.
A sixth field means seconds
Six fields still parse — the first is read as seconds, a note says so, and the builder bows out because five-field controls cannot edit a seconds schedule. Seven fields are Quartz and are refused with a hand-off that carries your text as typed — neither paste is ever a silent one-field shift.
Common errors
Field 2 (hour): '25' is outside 0–23- Each field's domain is fixed; the diagnostic names the field and its bounds — here, hours run 0 through 23.
Expected 5 fields, found 4 — did you omit the minute field?- Five columns exactly; a four-column paste has almost always lost its leading minute — count from the left before assuming the first value is the hour.
Field 1 (minute): "*/0" uses step 0, which would never advance — use a step of 1 or more.- A step means every Nth value, so */0 would advance nowhere; */1 and the plain wildcard are the same schedule.
Field 4 (day of month): "L" is Quartz syntax — L, W, # and ? do not exist in classic cron.- Quartz adds L, W, # and ? to the grammar, and dropping them quietly would change the schedule — the hand-off carries your expression over as typed.
Input is larger than the limit of 1,024 characters for this tool. To edit a schedule in place use the CLI: crontab -e- A refusal, never a truncation: the page evaluates all of your input or none. An overrun usually means a whole crontab file landed here — this tool wants one schedule.
FAQ
What do the five fields in a cron expression mean?
Left to right: minute (0–59), hour (0–23), day of month (1–31), month (1–12) and day of week (0–6, Sunday is 0 — a 7 is accepted and normalized to 0). A star leaves a field unrestricted; values, lists, ranges and steps narrow it.
How do I make a cron job run every 15 minutes?
Set the minute field to every-N with N = 15 and leave the rest on every: */15 * * * *. Runs land at :00, :15, :30 and :45; constrain hours or weekdays on top, as in the business-hours example.
Why did my job run on a day I never selected?
Because day of month and day of week were both filled in: that pair is an either-or match, so the 1st plus Monday runs on every 1st and on every Monday. Keep one of the two on every.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Recompute the next-runs preview from the current moment.
- ⌘/Ctrl + S
- Download the expression as .txt.
- ⌘/Ctrl + C
- Copy the built expression while nothing is selected.
- ⌘/Ctrl + Shift + C
- Copy the expression even over a selection.
- t
- Cycle the color theme.
- ? or ⌘/Ctrl + /
- Open the shortcut help dialog.
- Esc
- Close the topmost dialog.