Cron Expression Examples: Daily, Weekdays, Intervals and Leap Days
Cron expressions describe recurring wall-clock times compactly, but the same-looking schedule can behave differently across cron implementations. Traditional Unix cron uses five fields:
minute hour day-of-month month day-of-week
For example, 30 9 * * 1-5 means 09:30 Monday through Friday. Some schedulers add a leading seconds field or a trailing year field. Confirm the target system before copying an expression, then preview it in the Cron Builder.
Daily and weekday schedules
Common five-field examples are:
# Every day at 02:15
15 2 * * *
# Monday through Friday at 09:30
30 9 * * 1-5
# Saturday and Sunday at 08:00
0 8 * * 0,6
# First day of every month at midnight
0 0 1 * *
Many systems accept Sunday as 0; some also accept 7. Named values such as MON-FRI are not universal. Numeric fields are more portable, but always check the scheduler's documentation.
Intervals and boundaries
A step means “every matching value in this field,” not “wait this duration after the previous run”:
# Every 15 minutes within every hour
*/15 * * * *
# Every two hours at minute zero
0 */2 * * *
# Every 10 minutes during hours 09 through 17
*/10 9-17 * * 1-5
The last expression includes 17:50. If the intended final run is 16:50, use 9-16. Cron is not ideal for “exactly every 24 hours since deployment” or “30 minutes after the previous job finishes”; use an interval scheduler or queue with explicit state.
Ranges can cross neither midnight nor field boundaries in portable cron. To run every 20 minutes from 22:00 through 01:59, split the hour range:
*/20 22-23,0-1 * * *
Day-of-month and day-of-week surprise
In many traditional cron implementations, if both day-of-month and day-of-week are restricted, a run occurs when either field matches:
0 9 1 * 1
That may run on every Monday and on the first day of each month, not only when the first is Monday. Other schedulers use different semantics or require ? in one field. Avoid combining both fields unless you have verified the target behavior.
“Last day of month” is also implementation-specific. Quartz-style schedulers may support L, while standard cron usually does not. A portable pattern runs near month-end and checks tomorrow's month:
0 23 28-31 * *
# Exit unless tomorrow is in a different month.
[ "$(date -d tomorrow +\%m)" != "$(date +\%m)" ] || exit 0
run-month-end-job
BSD/macOS date uses different flags, so put calendar logic in a tested application when portability matters.
Leap days and impossible dates
This schedule matches February 29 at noon:
0 12 29 2 *
It runs only in leap years; cron does not “move” it to February 28. If the business rule means “the last day of February,” use explicit calendar logic instead. Similarly, 0 0 31 * * simply does not run in months without a 31st.
Use the Epoch Converter to verify concrete instants when investigating timestamps, but remember cron evaluates fields in a configured time zone.
Time zones, DST, and reliability
Document the scheduler's time zone explicitly. During daylight-saving transitions, a local time may not exist or may occur twice. Some schedulers skip or duplicate such runs; others compensate. For critical jobs, schedule in UTC or make the task idempotent and track the intended business date.
Common mistakes include assuming a six-field cloud expression is compatible with five-field Unix cron, forgetting that % has special meaning in some crontabs, and expecting cron to retry failures. Redirect output to managed logging, alert on missed or failed executions, prevent unintended overlap with a lock, and test the next several run times—including month ends and DST boundaries—before deployment.
Keep the expression next to a plain-language schedule, its time zone, owner, and expected maximum duration. That small operational contract makes reviews and incident response much less ambiguous.