Cron expression

Schedule

Type or paste a 5-field cron expression on the left to see what it means.

Success
Warning

Five fields, and the part everyone forgets is which day wins

A standard crontab(5) line has five time fields — minute, hour, day of month, month, day of week — followed by the command to run. This page reads either just the five fields, or a full copied line including the command: paste 0 2 * * 1-5 /usr/local/bin/nightly-backup.sh and it separates the schedule from the command automatically rather than choking on the command's own words.

The field almost nobody gets right the first time is the overlap between day-of-month and day-of-week. If both are restricted to something other than * — say 0 0 1,15 * 1 — cron does not require both conditions to hold. It runs when either matches: the 1st and 15th of the month, and every Monday. Most people expect an AND and get an OR, and the mistake is invisible until the job fires on a date nobody intended.

Two libraries do the actual parsing here rather than a hand-rolled one: cronstrue turns the expression into the English sentence, and cron-parser computes the actual next occurrences, timezone included. Getting ranges, steps, lists, and the day-of-week-is-also-day-0-and-7 rule right by hand is exactly the kind of thing a schedule parser is easy to get subtly wrong in.

This is the standard 5-field form only — the one crontab -e, systemd timer OnCalendar conversions, and most infrastructure tooling (Kubernetes CronJob, GitHub Actions schedule) all expect. Some schedulers — Quartz, node-cron — accept an optional sixth seconds field at the front; that variant is out of scope here on purpose, since it is not what a plain crontab file uses.

Everything runs in your browser. The expression never leaves the page — there is nothing here worth sending anywhere, but it is still computed locally rather than round-tripped to a server for no reason.

Reading a schedule

  1. Paste the expressionEither the five fields alone, or a full crontab line — the command after the fifth field is detected and shown separately, never treated as part of the schedule.
  2. Read the field breakdownEach of the five fields is labelled on its own, so a typo in the wrong column is easy to spot rather than buried in one long string.
  3. Check the next run timesSwitch the timezone to match where the job actually runs — a schedule read against the wrong timezone is the second most common cron surprise, right after the day-of-month/day-of-week overlap above.

A crontab's 0 2 * * * almost never means "2 AM where I am." Most systems run cron in UTC or the server's local timezone, not the timezone of whoever wrote the line — and neither is your laptop's timezone by default. If a job is landing at the wrong hour, check what timezone the box is actually in (timedatectl on a systemd host) before assuming the expression is wrong.

A real nightly backup line

A crontab line copied straight out of a server — the kind of thing that gets pasted here specifically because the six fields blur together at a glance.

Schedule and command, split apartweekday nights
Pasted linecrontab(5)
0 2 * * 1-5 /usr/local/bin/nightly-backup.sh --verbose
Parseddescription + fields
Description
At 02:00 AM, Monday through Friday

Command
/usr/local/bin/nightly-backup.sh --verbose

When you need this

Reviewing a schedule before it ships

A pull request adds or edits a cron line in a deployment manifest or an infrastructure file. Pasting the expression here before approving turns "looks about right" into an actual sentence and a list of real timestamps to check against the intended maintenance window.

Debugging "the job ran at the wrong time"

The day-of-month/day-of-week OR behaviour and timezone mismatches above account for most of these reports. Seeing the field breakdown and the next few runs in the server's actual timezone usually explains it faster than re-reading the crontab file line by line.

Writing a new schedule from scratch

Typing a guess and immediately seeing both the English description and the literal next run times catches an off-by-one field before it reaches a crontab file — cheaper than finding out at 3 AM that a job fired for the whole weekday range instead of one day.

Translating between infrastructure tools

Kubernetes CronJob.spec.schedule, GitHub Actions on.schedule.cron, and a plain crontab entry all use the identical 5-field grammar, so a schedule read here transfers directly to any of them.

What this page does

  • Parses a bare 5-field expression, or a full crontab line — the trailing command is detected and shown separately rather than breaking the parse.
  • Produces an English description via cronstrue, and a labelled breakdown of all five fields.
  • Computes the actual next run times via cron-parser, in any IANA timezone your browser knows.
  • Runs entirely client-side — nothing about the schedule you are checking is sent anywhere.

Questions people actually ask

Why does my job run on days I did not expect?

If both the day-of-month and day-of-week fields are restricted (neither is a bare *), crontab(5) runs the job when either matches, not both. 0 0 1,15 * 1 fires on the 1st, the 15th, and every Monday — three different reasons to run, not one combined condition.

Does this support the seconds field some schedulers use?

No — this page is the standard 5-field crontab(5) grammar on purpose, the one a plain crontab file, a Kubernetes CronJob, and a GitHub Actions schedule all expect. Quartz and node-cron's optional leading seconds field is a different, scheduler-specific extension and is out of scope here.

What does <code>*/15</code> actually mean?

A step value — every 15th unit starting from the field's minimum. In the minute field, */15 means minutes 0, 15, 30 and 45. It is shorthand for the explicit list 0,15,30,45, and both forms parse to the identical schedule.

Why do the next run times change when I switch timezone?

The five fields describe wall-clock time in whatever timezone the schedule is evaluated in — cron itself has no idea which one you meant unless the system it runs on tells it. Switching the timezone here recomputes the same 0 2 * * * against a different wall clock, which is exactly what happens when the same crontab line runs on a UTC server versus a machine set to local time.

Is Sunday day 0 or day 7 in the day-of-week field?

Both — crontab(5) accepts 0 through 7 for day-of-week and treats both 0 and 7 as Sunday, so 0 9 * * 0 and 0 9 * * 7 are the identical schedule. Worth knowing before assuming a 7 in that field is a typo.

Related tools

Specifications and references

  • Kubernetes CronJob – One of several infrastructure tools that use the identical 5-field grammar