Quartz Cron Expression Guide

A Quartz cron expression has six or seven fields, starting with seconds, and uses ? in one day field. Build one below, then see how Spring in Java reads the same text differently.

Last updated: October 8, 2026

The short answer

A Quartz cron expression has six fields, seconds minutes hours day-of-month month day-of-week, plus an optional year. You must put ? in one of the two day fields. Weekdays at 9:00:00 looks like this:

0 0 9 ? * MON-FRI
Second0
Minute0
Hour9
Day of month?
Month*
Day of weekMON-FRI

Spring, which most Java applications use through @Scheduled, reads similar text but without a year and with different weekday numbers.

Build a Quartz cron expression

Set the fields and the output follows Quartz rules, with the next runs in your time zone. Copy the result or open it in the full Generator.

Quartz cron expression syntax

Quartz expressions are six or seven fields separated by white space. The first field is seconds, which is the biggest change from Linux cron.

FieldRequiredValuesSpecial characters
SecondsYes0-59, - * /
MinutesYes0-59, - * /
HoursYes0-23, - * /
Day of monthYes1-31, - * ? / L W
MonthYes1-12 or JAN-DEC, - * /
Day of weekYes1-7 or SUN-SAT, - * ? / L #
YearNoempty, or 1970-2099, - * /

Quartz documents that support for restricting both a day of week and a day of month is not complete, so you must use ? in one of them. It means "no specific value".

Quartz cron expression examples

The first rows convert common Linux schedules; the rest use Quartz-only features. Load any of them into the builder above.

ExpressionWhat it doesUse
0 */5 * * * ?Runs every 5 minutes.
Quartz needs the leading seconds field.
Load
0 0 9 ? * MON-FRIRuns at 9:00 AM every weekday (Mon-Fri). Load
0 0 0 * * ?Runs at 12:00 AM every day. Load
0 0 0 L * ?Runs at 12:00 AM on the last day of every month.
Last day of the month.
Load
0 15 10 L-2 * ?Runs at 10:15 AM 2 days before the end of every month.
Two days before the end of the month, 10:15.
Load
0 15 10 ? * FRI#3Runs at 10:15 AM on the third Friday of every month.
Third Friday of the month, 10:15.
Load
0 0 12 */5 * ?Runs at 12:00 PM on days 1, 6, 11, 16, 21, 26 and 31 of every month.
Noon every 5 days, starting on the 1st.
Load

Java cron expression: Quartz versus Spring

In Java, "cron expression" usually means one of two things, and they are not identical. Quartz is a scheduling library with its own parser. Spring has its own, used by @Scheduled and CronExpression. Spring's documentation points out that Quartz deviates from common cron conventions for weekday numbers, while Spring follows them.

ItemQuartzSpring (@Scheduled, CronExpression)
Fields6 or 7: seconds first, optional year6: seconds first, no year
Day of week1-7 with 1 as Sunday, or names0-7 with 0 and 7 as Sunday, or names
The question markRequired in one day fieldAllowed in place of *
L, W, #SupportedSupported, with its own weekday numbers
Macros such as @dailyNoYes
Time zoneSet on the trigger, else the JVM defaultThe zone attribute on @Scheduled, else the server default

The weekday difference is the dangerous one. 6 is Friday in Quartz and Saturday in Spring. Use names such as FRI in both and the problem disappears.

// Quartz: set the time zone on the trigger
CronScheduleBuilder.cronSchedule("0 0 9 ? * MON-FRI")
    .inTimeZone(TimeZone.getTimeZone("America/New_York"));

// Spring: no ? needed, zone is an attribute
@Scheduled(cron = "0 0 9 * * MON-FRI", zone = "America/New_York")
public void sendReport() { ... }

CronWave's builder writes Quartz syntax. For Spring, remove the year if there is one, and check any numeric weekday.

Common mistakes with Quartz cron expressions

  • Pasting a five-field Linux expression. It is missing the seconds field, so every value shifts one place. Use the validator to see the offending field.
  • Using * in both day fields. One must be ?.
  • Combining L or W with lists or ranges. Quartz warns that the results are confusing or unsupported.
  • Expecting # to fire in months without that occurrence. There is no fifth Friday in some months, so nothing runs.
  • Forgetting that the default time zone is the JVM's, which differs between your laptop and your server.

Sources and further reading