Skip to content
CronChief

Cron special characters: L, W, # and ? explained

Standard cron has four symbols. Quartz-style cron adds L, W, # and ? — the keys to schedules like “last day of the month” and “the first Monday” that plain cron can't express.

Standard cron gives you four symbols — *, ,, - and / — covered in the syntax guide. They handle almost everything, but not "the last day of the month" or "the first Monday". For those, some schedulers add four more characters: L, W, # and ?. Here's what each does.

These are extensions, not standard Unix cron. They come from the Quartz scheduler and appear in Quartz, Spring's @Scheduled, AWS EventBridge and others. Plain Vixie cron (the /etc/crontab on your Linux box) does not understand them.

? — no specific value

? means "no specific value" and is only valid in the day-of-month and day-of-week fields. Because those two fields interact, schedulers like Quartz and AWS make you put ? in one of them to say "I'm not specifying this one — use the other". For example, "9 AM every weekday" in Quartz is:

0 0 9 ? * MON-FRI

The ? in day-of-month says "the weekday field is in charge here".

L — last

L means "last", and its meaning depends on the field:

  • In day-of-month, L is the last day of the month — the 28th, 30th or 31st as appropriate. So 0 0 L * ? runs at midnight on the last day of every month.
  • L-3 means the third-from-last day of the month.
  • In day-of-week, L means the last day (Saturday), and 5L means the last Friday of the month.

This solves a genuinely common need — "run on the last day of the month" — that standard cron simply cannot express.

W — nearest weekday

W means "the nearest weekday (Mon–Fri) to a given day". 15W in the day-of-month field runs on the weekday closest to the 15th: if the 15th is a Saturday, it runs on Friday the 14th; if it's a Sunday, on Monday the 16th. LW combines the two — the last weekday of the month. Handy for "pay on the nearest business day".

# — the nth weekday of the month

# picks the nth occurrence of a weekday. In the day-of-week field, dayOfWeek#n means "the nth such day". So 6#3 is the third Friday of the month (with Sunday = 1, Friday = 6 in Quartz numbering), and 2#1 is the first Monday. This is how you express "the first Monday of every month" — something plain cron gets wrong because it ORs the two day fields.

Support varies by scheduler

Character Unix cron Quartz Spring @Scheduled AWS EventBridge
? No Yes Yes Yes
L No Yes Yes Partly
W No Yes Yes Partly
# No Yes Yes Yes

Numbering also differs — Quartz and AWS use day-of-week 1–7 with Sunday = 1, whereas Unix cron uses 0–6 with Sunday = 0. Always confirm against your target system's docs, and see the cross-system guide for the wider picture.

The takeaway

If you only run classic Linux cron, stick to the four standard symbols and handle "last day" or "first Monday" logic inside your script. If your scheduler is Quartz, Spring or AWS, L, W, # and ? let you express those schedules directly — just remember they're a different dialect from the crontab on your server.