Cron Expression Explainer — read the schedule before you deploy it
A cron expression is dense by design: five or six space-separated fields decide when a backup runs, when a report is sent, or when a reprocessing job hits production. Reading 0 0 1 * 1 from memory and getting it right is harder than it looks — and the cost of being wrong only surfaces later, in production. This tool translates the expression into plain language and projects the real next runs, entirely in your browser.
How to use it
- Paste or type the expression — the explanation updates as you type.
- Check the field table to see exactly which values each position matches.
- Read the next runs with the relative countdown beside them. If the first date isn't what you expected, the expression is wrong.
- Use the examples as a starting point for the most common schedules.
The fields of a cron expression
| Position | Field | Range |
|---|---|---|
| 1 (6-field only) | Second | 0–59 |
| 2 | Minute | 0–59 |
| 3 | Hour | 0–23 |
| 4 | Day of month | 1–31 |
| 5 | Month | 1–12 or JAN–DEC |
| 6 | Day of week | 0–7 or SUN–SAT (0 and 7 both mean Sunday) |
Syntax accepted in each field
*— any value?— same as*(used by Quartz in the day fields)5— an exact value1,15,30— a list of values1-5— a continuous range*/15— every 15 units, starting from the beginning of the range10-30/5— a step inside a rangeMON-FRI,JAN,JUL— names instead of numbers
Unix (5 fields) versus Spring and Quartz (6 fields)
This is the trap that causes the most incidents. Unix crontab works at minute resolution and uses five fields. Spring's @Scheduled and Quartz add a seconds field at the front, for six in total. Copying an expression from a crontab article straight into a @Scheduled annotation shifts every field by one position: what was the minute becomes the second, and the job starts running hourly instead of once a day. This tool detects which of the two formats you typed and warns you when it reads the expression as six fields.
The OR rule between day of month and day of week
When both day fields are something other than *, cron combines them with OR, not AND. The expression 0 0 1 * 1 does not mean "the first Monday of the month": it fires on the 1st of every month and also on every Monday. To restrict it properly, leave one of the two fields as* and do the extra check inside the job itself.
Timezone: where the schedule really runs
Cron has no timezone of its own — it uses whatever the running process has. A UTC container, a server inAmerica/Sao_Paulo and your laptop produce three different results for the same expression. The simulation on this page uses your browser timezone, shown above the list; compare it against your production environment (in Spring, the zone attribute of @Scheduled) before calling the schedule correct.
Shorthands
@yearly/@annually—0 0 1 1 *@monthly—0 0 1 * *@weekly—0 0 * * 0@daily/@midnight—0 0 * * *@hourly—0 * * * *@reboot— at system startup (no predictable future time)
Everything runs in your browser
The expression is never sent to a server. All parsing and date projection happen locally, which matters when the expression comes out of a production configuration file.