Cron Expression
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.
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.
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.
| 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.
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
0 0 28-31 * * fires at midnight on days 28, 29, 30, and 31 — every possible month-end candidate.date -d tomorrow +%d prints tomorrow’s day number. It equals 01 only when today is the last day of the month, so the && gate runs your script exactly once per month.% is escaped as \% because crontab treats a bare % as a newline.On BSD/macOS, date -d isn’t available — use date -v+1d +%d instead.
L DirectlyIf 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.
Month-end jobs are the mirror image of first-of-month ones:
crontab -e
/path/to/script.sh with your job30 23 28-31 * * [ "$(date -d tomorrow +\%d)" = "01" ] && /path/to/script.sh
0 0 28-31 * * /path/to/month-end.sh with the script exiting early unless tomorrow is the 1st