Cron Expression Cheat Sheet

Cron syntax looks cryptic until you've memorized it, then you forget it again the moment you switch jobs. This is the reference: every field, both major dialects, and the mistakes that pass validation but run at the wrong time.

reference guide Hangfire Quartz.NET

// the two dialects

Almost every scheduler you'll meet uses one of two cron dialects. Standard cron (what Hangfire, Linux crontab, and most CI systems use) has 5 fields: minute, hour, day-of-month, month, day-of-week. Quartz.NET adds a leading seconds field and uses ? instead of * in whichever of day-of-month/day-of-week isn't in use — 6 fields total (a 7th, optional year field also exists but is rarely set).

field order
Standard / Hangfire (5 fields)minute hour day-of-month month day-of-week
Quartz.NET (6 fields)second minute hour day-of-month month day-of-week

// special characters

syntax
*every value in this field
,a list — MON,WED,FRI
-a range — 9-17 means 9 through 17
/a step — */15 means every 15 units, starting at 0
?"no specific value" — Quartz.NET only, used on whichever of day-of-month/day-of-week you're not constraining
L"last" — Quartz.NET only; last day of the month, or last given weekday
#"nth weekday of the month" — Quartz.NET only; 6#3 = third Friday

// common schedules, both dialects

examples
Every minute* * * * * / 0 * * * * ?
Every 15 minutes*/15 * * * * / 0 */15 * * * ?
Every hour, on the hour0 * * * * / 0 0 * * * ?
Daily at 2:30 AM30 2 * * * / 0 30 2 * * ?
Every weekday at 9 AM0 9 * * 1-5 / 0 0 9 ? * 2-6
Every Monday at 6 AM0 6 * * 1 / 0 0 6 ? * 2
First day of every month, midnight0 0 1 * * / 0 0 0 1 * ?
Every 6 hours0 */6 * * * / 0 0 */6 * * ?

// mistakes that pass validation but run wrong

Setting both day-of-month and day-of-week to specific values doesn't mean "AND" — in standard cron it means "OR" (either condition triggers it), which almost never matches what you intended. If you want a specific weekday, leave day-of-month as *.
Day-of-week numbering differs by dialect: standard cron is 0–6 with 0 = Sunday. Quartz.NET is 1–7 with 1 = Sunday. The same digit means a different day depending which dialect you're reading — always check which one you're in before trusting a number.
Cron expressions run in whatever timezone the scheduler process is configured for — not necessarily UTC, and not necessarily the server's local time if the app sets one explicitly. A schedule that looks right can drift by hours after a timezone or daylight-saving change if this isn't pinned down.
A step value like */5 always starts counting from the field's zero point, not from "5 units from now." */5 on minutes fires at :00, :05, :10 — never at :02, :07, :12, no matter what minute you deployed at.

// try it yourself

Build a schedule field-by-field, or paste an existing expression to get a plain-English explanation and its next five run times, with the Cron Builder & Explainer.