Cron Expression Parser
Translate a cron expression into plain English, and see exactly when it next runs.
Read in the server’s local time zone, which is often UTC.
| Field | Matches |
|---|---|
| minute | 30 |
| hour | 9 |
| day of month | every (1–31) |
| month | every (1–12) |
| day of week | 1, 2, 3, 4, 5 |
Next-run times use your browser’s time zone. A server almost always runs on UTC, so the actual firing times will differ unless you are on UTC yourself.
A cron expression has five fields: minute, hour, day of month, month, and day of week. So 30 9 * * 1-5 reads as 09:30 on Monday through Friday, and */15 * * * * means every fifteen minutes.
Five fields, read left to right
Cron schedules are compact to the point of being cryptic, but the structure is simple: five space-separated fields, each describing one unit of time, from the smallest to the largest. A field matches either everything (*) or a specific set of values.
The syntax within a field is where the expressiveness comes from. A list (1,15) matches several values. A range (1-5) matches everything between two. A step (*/15) matches every nth value, and steps can be applied to ranges too — 9-17/4 gives 9, 13, and 17.
The trap in the two day fields
Cron has two ways to specify days: day of month and day of week. When both are restricted, cron does not require both to match — it runs when either does. So 0 0 1 * 1 fires on the first of the month and on every Monday, not only on Mondays that fall on the first.
This surprises almost everyone, because every other field is combined with AND. It is a genuine quirk of the original implementation, preserved for compatibility, and this parser flags it when both fields are set.
Within any field: * matches all, a,b lists values, a-b gives a range, */n steps, and a-b/n steps within a range. Month and weekday names such as JAN and MON also work.
Reading an expression
Take 30 9 * * 1-5 field by field:
- 1 Minute: 30. The job runs at 30 minutes past the hour — not every minute.
- 2 Hour: 9. Only during the 9 o’clock hour, so 09:30 rather than half past every hour.
- 3 Day of month: *. Any day of the month — this field imposes no restriction.
- 4 Month: *. Every month.
- 5 Day of week: 1-5. Monday through Friday. Zero is Sunday, so 1–5 is the working week.
- 6 Put it together. At 09:30, Monday to Friday — a weekday-morning job.
Common schedules
The patterns that cover most real scheduling needs.
| Expression | Meaning |
|---|---|
| * * * * * | Every minute |
| */5 * * * * | Every five minutes |
| 0 * * * * | Every hour, on the hour |
| 0 3 * * * | Daily at 03:00 |
| 30 9 * * 1-5 | Weekdays at 09:30 |
| 0 0 * * 0 | Weekly, Sunday at midnight |
| 0 0 1 * * | Monthly, on the 1st at midnight |
| 0 0 1 1 * | Yearly, on 1 January |
| 0 9-17/4 * * * | At 09:00, 13:00, and 17:00 |
Time zones and portability
Cron runs in the server's local time zone, which on most infrastructure is UTC. A schedule that looks like a sensible 09:00 start can therefore fire in the middle of the night for the team reading its output. The next-run times shown here use your browser's zone, so compare them against what the server is actually set to.
Daylight saving adds a further wrinkle on servers that do use a local zone: when clocks go forward, a job scheduled inside the skipped hour may not run at all, and when they go back it may run twice. Scheduling outside the 01:00–03:00 window avoids the problem entirely.
One portability note. Some schedulers — notably Quartz, used in the Java ecosystem — extend the syntax with ?, L, W, and #, and add a seconds field at the front. Those are not standard cron, so this parser rejects them rather than guessing: an expression that means one thing in Quartz and another in Unix cron is worse than one that fails loudly.