Quartz cron expressions: seconds-first scheduling for Java
Quartz is the de-facto job scheduler of the Java world, embedded in countless Spring, Jenkins-adjacent and
enterprise applications. Its cron syntax is a superset of the Unix one — with a seconds field in front, an
optional year at the end, and stricter day-field rules. If you have ever pasted
0 0/5 * * * ? into a crontab and been rejected, this page explains why. For standard 5-field
cron, our interactive generator does the work for you.
The seven fields
| Position | Field | Values | Special characters |
|---|---|---|---|
| 1 | Seconds | 0–59 | , - * / |
| 2 | Minutes | 0–59 | , - * / |
| 3 | Hours | 0–23 | , - * / |
| 4 | Day of month | 1–31 | , - * / ? L W |
| 5 | Month | 1–12 or JAN–DEC | , - * / |
| 6 | Day of week | 1–7 or SUN–SAT (1 = Sunday) | , - * / ? L # |
| 7 | Year (optional) | e.g. 2026, ranges | , - * / |
Six fields are the minimum; the year is optional, so both 0 0 12 * * ? and
0 0 12 * * ? 2026 are valid. The leading seconds field means every Unix-style position is
shifted one to the right — mechanical, but easy to fumble when converting by eye.
Reading some real Quartz schedules
| Expression | Meaning |
|---|---|
0 0/5 * * * ? | Every 5 minutes (at second 0) |
0 0 * * * ? | Every hour on the hour |
0 0 0 * * ? | Every day at midnight |
0 15 10 ? * MON-FRI | 10:15 on weekdays |
0 0 12 1 * ? | Noon on the 1st of every month |
0 0 9 ? * MON#2 | 09:00 on the second Monday of the month |
0 30 8 L * ? | 08:30 on the last day of the month |
*/10 * * * * ? | Every 10 seconds — impossible in crontab |
The ? requirement
Like AWS (which borrowed the convention from Quartz), you cannot constrain day-of-month and day-of-week at
the same time: exactly one of the two must be ?. This is why every generic Quartz example
ends in ? — the day-of-week slot is being explicitly vacated. Quartz also brings
L (last day / last weekday-of-month, e.g. 6L = last Friday), W
(nearest weekday to a date) and # (nth weekday, e.g. MON#2), none of which exist
in 5-field cron.
Sunday = 1, and the Spring lookalike
Quartz counts weekdays 1–7 starting at Sunday, so Unix 1-5 (Mon–Fri) is Quartz
2-6. Beware the lookalike: Spring Framework’s @Scheduled(cron = ...) also
takes a seconds-first 6-field string, but it follows Unix weekday numbering and happily accepts
* in both day fields. An expression copied between a Quartz job store and a Spring annotation
can silently change meaning — always re-check the weekday numbers when moving between the two.
Converting Quartz → Unix cron
- Confirm the seconds field is
0(anything else has no crontab equivalent). - Delete the seconds field and the year field.
- Replace
?with*. - Shift numeric weekdays down by one (
2-6→1-5), or keep names likeMON-FRI. - If the expression uses
L,Wor#, stop — move that logic into the script.
So 0 15 10 ? * MON-FRI becomes 15 10 * * MON-FRI, which you can paste into the
generator to verify: “At 10:15, Monday through Friday.”
FAQ
How many fields does a Quartz cron expression have?
Six or seven: seconds, minutes, hours, day-of-month, month, day-of-week, plus an optional year. The seconds field comes first, which is the quickest way to recognise a Quartz expression.
Why does Quartz require a ? in the day fields?
Quartz does not support specifying both day-of-month and day-of-week; exactly one of them must be ? ("no specific value"). Writing * in both is rejected as ambiguous by validators, so 0 0 12 * * ? is the canonical "every day at noon".
What number is Sunday in Quartz?
Quartz numbers day-of-week 1-7 with 1 = Sunday, like AWS and unlike Unix cron (where Sunday is 0 or 7). SAT is 7. Using names (SUN, MON …) avoids off-by-one bugs when porting.
Is Spring’s @Scheduled cron the same as Quartz?
No, and this catches many Java developers. Spring Framework has its own 6-field, seconds-first format that looks like Quartz but follows Unix weekday numbering (0-7 with both 0 and 7 = Sunday) and does not require ?. An expression can be valid in one and invalid in the other.
How do I convert a Quartz expression to standard cron?
Drop the seconds field (Quartz below one-minute precision cannot be expressed in crontab), drop the year if present, replace ? with *, and renumber weekdays down by one (Quartz 2-6 = Unix 1-5). L, W and # schedules have no 5-field equivalent and need a script-side check.
Related: AWS EventBridge cron expressions · cron every day at midnight · cron expression generator & explainer