What’s a cron expression? If you’re reading this, you probably already know what it’s for: when setting up scheduled tasks on Linux, Spring or Quartz, you write a cron expression to define the execution cycle. Cron is pronounced /krɒn/ — like “chron” in chronology.
Cron types
A cron expression is a string of five to seven space-separated fields — and Linux, Spring and Quartz differ, so we’ll discuss them separately. First, the general symbols valid everywhere. To test your own expressions, I also have an online cron tester.
Each space-separated field can use digits and the symbols , - * / ? L W #, with these meanings:
- Digits: a specific point in time
,: enumerates values — essentially “or”. 1,3 means 1 or 3-: a range. 1-3 means 1 through 3*: matches any value in the field — any number/: increments — essentially an interval. In the minutes field, 0/5 means starting at 0, every 5 minutes?: only allowed in the Day of Month and Day of Week fields; also means “any”. For example, to trigger on the 20th of each month regardless of weekday, you’d write 13 13 15 20 * ? — the last field must be ?, not *; using * would trigger on every weekdayL: “last”; only in Day of Week and Day of Month fields. 5L in Day of Week means the last ThursdayW: weekday (Mon–Fri); only in Day of Month. 5W: if the 5th is a Saturday, it triggers on the nearest weekday, Friday the 4th; if the 5th is a Sunday, it triggers on Monday the 6th; if the 5th is Monday–Friday, it triggers on the 5th#: the nth weekday of the month; only in Day of Week. 4#2 means the second Wednesday of the month
Since the field layout differs per system, let’s go through them one by one.
Linux (crontab)
Linux uses 5 fields: Minutes, Hours, Day of Month, Month, Day of Week.
Using the notation above, let’s build one: “at minutes 0 and 30, from 18:00 to 23:00”. That’s 0,30 18-23 * * * — 0,30 means minute 0 or 30; 18-23 means hours 18 to 23; the asterisks match anything.
Java (Spring)
Spring’s @Scheduled gives us scheduled tasks with 6 fields: Second, Minutes, Hours, Day of Month, Month, Day of Week.
Same as Linux, but with a seconds field added — precision down to the second. Let’s build one: “at 18:00 sharp on the 28th through 31st of each month”. That’s 0 0 18 28-31 * ? — the first 0 is 0 seconds, the second 0 is 0 minutes, 18 is 18:00, 28-31 is the 28th through 31st, the asterisk is any month, the question mark is any weekday.
Quartz
In the Quartz scheduler, a cron expression adds one more field on top of Spring’s — 7 fields: Second, Minutes, Hours, Day of Month, Month, Day of Week, Year (optional).
Quartz is the more professional scheduling framework, hence the year field. It’s optional — you can omit it entirely, and we usually do — but if you need to trigger in a specific year, it’s there.
Let’s practice one more: “at 18:00 sharp on the last day of every month” — a common one, month-end. That’s 0 0 18 L * ? — 0 seconds, 0 minutes, 18:00, L in the Day of Month field means the last day, the asterisk is any month, the question mark is any weekday.
Wrap-up
Once you understand what each field means, it’s easy — honestly much easier to learn than regex. Go play with the online cron tester and explore.
