Cron expression cheat sheet, with the fields people get wrong

Five fields, a handful of operators, and two traps that cause most misfires. A practical reference for reading and writing cron schedules.

The five fields

Standard cron is minute hour day-of-month month day-of-week — 0–59, 0–23, 1–31, 1–12, 0–6 (Sunday is 0, and many implementations also accept 7). Operators: * any value, , a list, - a range, / a step.

Patterns you will actually write

Trap one: day-of-month and day-of-week are OR, not AND

If both fields are restricted, cron fires when either matches. 0 0 13 * 5 does not mean “Friday the 13th” — it means midnight on the 13th and every Friday. To get a single condition, leave one field as *.

Trap two: whose clock?

Cron runs in the daemon's timezone. Move a container from UTC to a local zone and every schedule silently shifts, and DST transitions can make an hourly job run twice or not at all. Pin jobs to UTC where you can, and check the wall-clock impact with the Timezone tool.

Reading an unfamiliar expression

Paste it into the Cron Parser for a plain-English description and the next run times. If you are converting a polling interval into a schedule, the Duration Humanizer turns raw seconds into the span you are actually asking for.

Non-standard extensions

Many schedulers add a sixth seconds field (Quartz, Spring, some Go libraries), plus macros like @daily, @hourly and @reboot, and Quartz-only characters ?, L, W and #. These are not portable — an expression copied from a Quartz answer will often be rejected by plain crontab.

Tools used in this guide