Cron Expression: Cron Last Day of Month

Standard cron has no last-day-of-month syntax. Learn the 28-31 plus date-check idiom, and where Quartz's L expression works instead.

Cron Expression

0 0 28-31 * *

This entry fires on days 28-31; a one-line date check inside the command ensures the job itself only runs on the true last day of the month — see below.

Want to tweak this schedule?

Edit this expression in our interactive generator and see it broken down in real time.

Open in Cron Generator

Expression Breakdown

0
Minute
(0-59)
0
Hour
(0-23)
28-31
Day
(1-31)
*
Month
(1-12)
*
Weekday
(0-6)
Field Value Meaning
Minute 0 At minute 0
Hour 0 At hour 0
Day of Month 28-31 Days 28-31
Month * Any month
Day of Week * Any day of the week

Here’s an awkward truth: standard Unix cron has no “last day of month” syntax. Months end on the 28th, 29th, 30th, or 31st, and the day-of-month field can’t express “whichever is last.” The standard idiom: fire on all candidate days and let a date check pick the real one.

Cron Expression (the idiom)

0 0 28-31 * *

Combined with a date check in the command:

0 0 28-31 * * [ "$(date -d tomorrow +\%d)" = "01" ] && /path/to/script.sh

How It Works

On BSD/macOS, date -d isn’t available — use date -v+1d +%d instead.

Quartz and Friends Support L Directly

If you’re scheduling inside a Java app (Quartz), Spring, or another framework with Quartz-style expressions, you get real last-day support:

0 0 0 L * ?

The L in the day-of-month field means “last day.” Some modern cron replacements (and Oracle/Jenkins flavors) accept L too — but classic Linux crontab will reject it, so don’t paste Quartz syntax into crontab -e.

Use Cases

Month-end jobs are the mirror image of first-of-month ones:

How to Use

  1. Copy the full crontab line (expression + date check) from above
  2. Open your crontab with crontab -e
  3. Paste it, replacing /path/to/script.sh with your job
  4. Save, then sanity-check next month-end in the logs

Alternative Formats