Cron Expression Explainer

Developer

What a cron schedule really means, and the next five times it fires.

What it means
Every 15 minutes, every day.
minutehourday of monthmonthday of week
Next five runs
Thursday2026-01-01 00:15
Thursday2026-01-01 00:30
Thursday2026-01-01 00:45
Thursday2026-01-01 01:00
Thursday2026-01-01 01:15

These are wall-clock times. A cron schedule fires when the server clock reads the time, whatever the offset that day — the Philippines has not observed daylight saving since 1978, so it does not shift here.

Field by field
minute*/15 0, 15, 30, 45
hour* any
day of month* any
month* any
day of week* any

How to use

What it's for

Find out in plain words when a scheduled job will run, from the short cron line a server or an app uses — and see the exact times it will run next.

Before you start

Have the schedule line to hand, such as 0 9 * * 1-5, copied from a crontab, a server's settings or an app's documentation.

  1. Enter the schedule

    Type or paste it into Cron expression. It has five parts separated by spaces, and the labels under the box say what each one is: minute, hour, day of month, month and day of week. A * means "every".

  2. Or start from an example

    Press Every 15 min, Weekday 9am or Monthly to load a common schedule and change it from there. The OR trap loads the schedule people most often misread.

  3. Choose where to count from

    Leave Count forward from empty to list the runs coming up from now. Pick a date and time in it to see the runs after that moment instead.

  4. Explain

    Press Explain. The meaning at the top also updates as you type, so you can change one part and watch the sentence change.

Reading the result

  • What it means: the schedule in a plain sentence, such as "Every 15 minutes, every day."
  • Next five runs: the day, date and time of each coming run. They are clock times, so they are right for whatever time zone the server's clock is set to.
  • Field by field: each of the five parts as you wrote it, and the values it allows.

If it goes wrong

  • Your line has six parts and the page says Quartz and Spring put SECONDS in front: that kind of schedule starts with seconds. To use it in a crontab, delete the first part.
  • It runs on more days than you expected: when both the day of month and the day of week are set, it runs when EITHER matches — 0 0 13 * 5 is the 13th of every month and every Friday. To need both, set one here and check the other inside the job itself.
  • A message says the expression never fires: usually it names a day the month does not have, such as 30 February. Note too that a job set for day 31 is skipped in shorter months, not moved.

What this is

Cron has five fields: minute hour day-of-month month day-of-week. That part is easy. The hard part is how the two day fields combine.

When both day-of-month and day-of-week are restricted, cron fires when EITHER matches — not when both do. So 0 0 13 * 5 is not Friday the 13th. It is midnight on the 13th of every month and midnight every Friday: roughly sixty runs a year, not one or two.

Nothing in crontab warns you. The job you thought ran annually quietly runs sixty times.

The other trap is a day that does not exist. 0 0 31 * * fires seven times a year — cron skips the shorter months rather than moving the run to the 30th. For the last day of the month, schedule it daily and test the date inside the job.

Questions

Does “0 0 13 * 5” mean Friday the 13th?

No, and this is the most misread rule in cron. When BOTH the day-of-month and day-of-week fields are restricted, POSIX cron fires when EITHER matches — not when both do. That expression runs at midnight on the 13th of every month AND at midnight every Friday: roughly sixty runs a year rather than one or two. To require both conditions, restrict one field and test the other inside the job itself.

My expression has six fields and this rejects it. Why?

Because six fields means Quartz or Spring, which put SECONDS in front. Unix crontab takes five, starting at the minute. The two are not interchangeable: “0 0 12 * * ?” is noon in Quartz and nonsense in a crontab. Dropping the leading field to make it fit would produce a plausible, wrong schedule, so it is refused with the reason instead.

What happens on the 31st in a month that has 30 days?

Nothing — cron skips it rather than moving the run to the 30th or the 1st. “0 0 31 * *” fires seven times a year, and “0 0 30 * *” never fires in February. If you want the last day of the month, schedule it daily and test the date inside the job.

Is Sunday 0 or 7?

Both, in every real cron. Day-of-week runs 0 to 7 with Sunday at each end, which is why “* * * * 0” and “* * * * 7” are the same schedule. This accepts either and folds 7 onto 0.

Are the run times in my timezone?

They are wall-clock times, which is how cron itself works: “0 3 * * *” means “when the server clock reads 03:00”, whatever the UTC offset is that day. So the list is correct for whatever zone your server is in. On a server that observes daylight saving, a time inside the skipped hour never runs and a time inside the repeated hour may run twice — that does not arise in the Philippines, which has not observed DST since 1978.

Why does it reject L, W and #?

Those are Quartz extensions: L is “last”, W is “nearest weekday”, and # is “the nth of the month”. No Unix crontab understands them. Reading “5L” as plain 5 would give you a run list that is confidently wrong, so it is named and refused instead.

The maths

How the two day fields combine
Day = *, weekday = *every day
Only day-of-month setday only
Only day-of-week setweekday only
Both setday OR weekday
Only the last row surprises anyone — and it is where almost everyone gets it wrong. To require both, restrict one field in cron and test the other inside the job.

Keep going

Important

Runs entirely in your browser; nothing is transmitted. Standard five-field Unix cron only — Quartz syntax (six fields, L, W, #) is named and refused rather than guessed at. Run times are wall-clock times, which is how cron itself works. Nothing you type here is sent to our servers — the calculation runs entirely in your browser.