CalcOpenly
English

Cron expression parser and explainer

Explain a five-field cron expression and list its next run times after any start date and time, in UTC.

Drafted with AI writing toolsUpdated Checked examples: 7

minute hour day-of-month month day-of-week, e.g. 30 2 * * 1: or @hourly, @daily, @weekly, @monthly, @yearly.
= 2026-11-12
Runs are listed strictly after this moment.
More options
Try
Next run
Thu 2026-11-12 09:00 UTC
Next run: Thu 2026-11-12 09:00 UTC
In plain language
Every 15 minutes, during hours 09 through 17, on Monday through Friday
Upcoming runs
Thu 2026-11-12 09:00 UTC Thu 2026-11-12 09:15 UTC Thu 2026-11-12 09:30 UTC Thu 2026-11-12 09:45 UTC Thu 2026-11-12 10:00 UTC Thu 2026-11-12 10:15 UTC Thu 2026-11-12 10:30 UTC Thu 2026-11-12 10:45 UTC Thu 2026-11-12 11:00 UTC Thu 2026-11-12 11:15 UTC
Time until the next run
9 h
Runs on each matching day
36
Times are UTC. A cron daemon uses its server's time zone (or CRON_TZ), so shift these if the server isn't on UTC.

Every 15 minutes, during hours 09 through 17, on Monday through Friday. The next run after the start is Thu 2026-11-12 09:00 UTC, followed by Thu 2026-11-12 09:15 UTC.

Next runs

09:00: 2026-11-1209:002026-11-1209:15: 2026-11-1209:152026-11-1209:30: 2026-11-1209:302026-11-1209:45: 2026-11-1209:452026-11-1210:00: 2026-11-1210:002026-11-1210:15: 2026-11-1210:152026-11-1210:30: 2026-11-1210:302026-11-1210:45: 2026-11-1210:452026-11-1211:00: 2026-11-1211:002026-11-1211:15: 2026-11-1211:152026-11-12
Upcoming runs (UTC) Rows: 10
#Run
1Thu 2026-11-12 09:00 UTC
2Thu 2026-11-12 09:15 UTC
3Thu 2026-11-12 09:30 UTC
4Thu 2026-11-12 09:45 UTC
5Thu 2026-11-12 10:00 UTC
6Thu 2026-11-12 10:15 UTC
7Thu 2026-11-12 10:30 UTC
8Thu 2026-11-12 10:45 UTC
9Thu 2026-11-12 11:00 UTC
10Thu 2026-11-12 11:15 UTC
How it's calculated S
  1. Minute: */15

    Values (4): 0, 15, 30, 45.

  2. Hour: 9-17

    Values (9): 9, 10, 11, 12, 13, 14, 15, 16, 17.

  3. Day of month: *

    Every day of month.

  4. Month: *

    Every month.

  5. Day of week: MON-FRI

    Values (5): Mon, Tue, Wed, Thu, Fri.

  6. Combine the two day fields

    At least one day field starts with *, so a day must match both (with * matching everything).

  7. Scan forward

    Starting after 2026-11-12 00:00 UTC, check each day, then each matching hour and minute, until 10 runs are found.

About the cron expression parser and explainer

A cron expression has five fields: minute (0–59), hour (0–23), day of month (1–31), month (1–12 or JAN–DEC) and day of week (0–7 or SUN–SAT, where 0 and 7 both mean Sunday). Each field takes a single value, a comma-separated list, a range with a hyphen or a step with a slash. The parser expands every field into its set of values, then scans forward day by day for the minutes that match all five.

The default, */15 9-17 * * MON-FRI, runs every 15 minutes from 09:00 to 17:45 on weekdays, which is 36 runs on each matching day. Started at midnight on Thursday 15 January 2026, its first run is 09:00 that morning.

When day of month and day of week are both restricted, cron runs on days that match either one, as crontab(5) specifies. Times here are UTC; a cron daemon uses its server's time zone, or CRON_TZ in cronie.

How to read a cron expression

A cron expression has five fields, read left to right: minute, hour, day of month, month and day of week. An asterisk means every value. 30 2 * * 1 runs at 02:30 every Monday, and */15 9-17 * * MON-FRI runs every 15 minutes from 09:00 through 17:45 on weekdays, 36 times a day.

The five fields

  1. Minute: 0–59
  2. Hour: 0–23
  3. Day of month: 1–31
  4. Month: 1–12, or JAN–DEC
  5. Day of week: 0–7, or SUN–SAT, where 0 and 7 both mean Sunday

Each field takes * for every value, a single number, a list with commas (5,20,50), a range with a hyphen (9-17) or a step with a slash (*/15, 10-40/15). Names are case-insensitive.

The crontab(5) manual for cronie and Vixie cron defines this grammar, the format most Linux crontabs follow.

Common cron schedules

  • Every 5 minutes: */5 * * * *, 288 runs a day
  • Every hour on the hour: 0 * * * *, or @hourly
  • Every day at midnight: 0 0 * * *, or @daily
  • Every day at 02:30: 30 2 * * *
  • Weekdays at 09:00: 0 9 * * 1-5
  • Every Sunday at midnight: 0 0 * * 0, or @weekly
  • The first of every month at midnight: 0 0 1 * *, or @monthly
  • Every 1 January at midnight: 0 0 1 1 *, or @yearly

How steps work

A step counts from the start of its range and restarts every hour or day. */15 in the minute field means 0, 15, 30 and 45, and 10-40/15 means 10, 25 and 40.

Because steps restart, they are not always even intervals. */35 * * * * fires at minutes 0 and 35, so the gaps alternate between 35 and 25 minutes.

0 */5 * * * fires at 00:00, 05:00, 10:00, 15:00 and 20:00, then waits only 4 hours for midnight. To start a step elsewhere, give a range: 1-59/5 runs at minutes 1, 6, 11 and so on.

When both day fields are set

If day of month and day of week are both restricted, cron runs when either one matches. 0 12 1 * MON fires at noon on the 1st of every month and on every Monday, not only on Mondays that fall on the 1st.

In cronie and Vixie cron, a day field that starts with * switches this to AND. 0 0 */2 * FRI therefore runs only on Fridays with odd dates, because */2 counts days 1, 3, 5 and onward.

Next runs for five schedules

ScenarioFirst next runRuns per matching day
DefaultThu 2026-01-15 09:00 UTC36
Every five minutesThu 2026-01-15 12:40 UTC288
Leap daysTue 2028-02-29 00:00 UTC1
Month day or MondayMon 2026-01-19 12:00 UTC1
Star day step ANDFri 2026-01-23 00:00 UTC1

Default is */15 9-17 * * MON-FRI. Every row starts on 15 January 2026 at 00:00 UTC except Every five minutes, which starts at 12:35 and first fires at 12:40, because runs are listed strictly after the start.

Leap days is 0 0 29 FEB *, and the last two rows are the day-field examples above. Runs per matching day counts time slots on a day that matches, even though most years have no 29 February.

Time zones and daylight saving

These run times are in UTC. A cron daemon uses the server's local time zone unless the crontab sets CRON_TZ (in cronie).

On a daylight-saving changeover day, a job at 02:30 local time can be skipped or shifted. Servers that run on UTC avoid the problem.

Common cron mistakes

  • * 9 * * * for "9 a.m." That runs every minute from 09:00 to 09:59, 60 times. Write 0 9 * * *.
  • Six fields. Quartz and Spring put a seconds field first, as in 0 0/15 * * * ?. Crontab takes five fields, and ?, L, W and # belong to those other dialects.
  • Wrapping ranges. 22-2 is rejected here; write 22-23,0-2 for 22:00 through 02:00.
  • An unescaped % in the command. Crontab turns % in the command part into a newline, so date +%F must be written date +\%F.
  • Impossible dates. 0 0 30 2 * never runs, because February has no 30th.

Supported syntax and search range

  • Five fields, or one of @hourly, @daily, @midnight, @weekly, @monthly, @yearly and @annually. @reboot has no calendar time to list.
  • Up to 50 upcoming runs, found by searching a full 400-year Gregorian cycle, so rules such as 2100 not being a leap year are covered.

For the gap between two calendar dates, use the date difference calculator.

Worked examples

Every 15 minutes in office hours

Cron expression
*/15 9-17 * * MON-FRI
Start date (UTC)
2026-01-15
Start time (UTC)
00:00
Next run
Thu 2026-01-15 09:00 UTC
Upcoming runs
Thu 2026-01-15 09:00 UTC Thu 2026-01-15 09:15 UTC Thu 2026-01-15 09:30 UTC Thu 2026-01-15 09:45 UTC Thu 2026-01-15 10:00 UTC Thu 2026-01-15 10:15 UTC Thu 2026-01-15 10:30 UTC Thu 2026-01-15 10:45 UTC Thu 2026-01-15 11:00 UTC Thu 2026-01-15 11:15 UTC
Runs on each matching day
36
Time until the next run
9 h

Checked against: 4 minutes × 9 hours = 36 runs a day; 09:00 − 00:00 = 32400 s

Daily at 09:00, starting exactly at 09:00 (edge)

Cron expression
0 9 * * *
Start date (UTC)
2026-01-15
Start time (UTC)
09:00
Runs to list
3
Next run
Fri 2026-01-16 09:00 UTC
In plain language
At 09:00, every day
Upcoming runs
Fri 2026-01-16 09:00 UTC Sat 2026-01-17 09:00 UTC Sun 2026-01-18 09:00 UTC

Checked against: crontab(5): runs are strictly after the start; confirmed by the brute-force scan

Leap day only

Cron expression
0 0 29 2 *
Start date (UTC)
2026-01-15
Start time (UTC)
00:00
Runs to list
3
Next run
Tue 2028-02-29 00:00 UTC
Upcoming runs
Tue 2028-02-29 00:00 UTC Sun 2032-02-29 00:00 UTC Fri 2036-02-29 00:00 UTC

Checked against: Independent calculation

Day 1 or Monday (both day fields restricted)

Cron expression
0 12 1 * MON
Start date (UTC)
2026-01-15
Start time (UTC)
00:00
Runs to list
5
Upcoming runs
Mon 2026-01-19 12:00 UTC Mon 2026-01-26 12:00 UTC Sun 2026-02-01 12:00 UTC Mon 2026-02-02 12:00 UTC Mon 2026-02-09 12:00 UTC

Checked against: crontab(5) OR rule for day-of-month and day-of-week, checked by the brute-force scan

Questions

What does */5 mean in a cron expression?

*/5 means every 5th value of the field, counted from the field's first value. In the minute field it fires at minutes 0, 5, 10 … 55, which is 12 times an hour. A step can follow a range too: 10-30/10 gives minutes 10, 20 and 30. Steps restart each hour, so */7 runs at minute 56 and then again at minute 0.

How do I run a cron job every day at midnight?

Write 0 0 * * *, which means minute 0 of hour 0 on every day, or use the @daily macro, which cronie and Vixie cron expand to the same five fields. For 2:30 a.m. every day write 30 2 * * *, and for 09:00 on weekdays write 0 9 * * 1-5. The hour is read in the server's time zone unless the crontab sets CRON_TZ.

How do day of month and day of week combine in cron?

If both fields are restricted, cron runs when either one matches, so 0 12 1 * MON fires at noon on the 1st of every month and on every Monday. In Vixie cron and cronie, a day field that starts with * switches this to both, which is why 0 0 */2 * FRI runs only on Fridays that fall on odd dates such as the 23rd.

Why does my cron expression have 6 or 7 fields?

Standard cron uses 5 fields. Quartz and Spring schedulers put a seconds field in front, making 6, and Quartz accepts an optional year as a 7th, so an expression like 0 0/15 * * * ? belongs to those tools rather than crontab; the ? placeholder is Quartz syntax. This parser reads the 5-field crontab format plus the @hourly, @daily, @weekly, @monthly and @yearly macros.

Can cron run a job every 30 seconds?

Not directly: the smallest unit in a crontab is 1 minute, because the first field is the minute. The usual workaround is two entries, * * * * * job and * * * * * sleep 30; job, which start the job at 0 and 30 seconds past each minute. systemd timers accept OnCalendar schedules down to the second if you need finer control.

About this calculator

run  ⟺  m∈M∧h∈H∧ month∈Mo∧dayday={DOM∨DOWboth≠∗DOM∧DOWotherwise\begin{aligned} \text{run} &\iff m \in M \land h \in H \\ &\qquad \land\ \text{month} \in Mo \land \text{day} \\ \text{day} &= \begin{cases} \text{DOM} \lor \text{DOW} & \text{both} \ne * \\ \text{DOM} \land \text{DOW} & \text{otherwise} \end{cases} \end{aligned}

Sources

  1. POSIX.1-2017 (IEEE Std 1003.1) — crontab utility, input file format
  2. crontab(5) — cronie / Vixie cron: ranges, steps, names, @ macros and the day-of-month / day-of-week rule

Checked against references

This calculator includes 7 worked examples with independently sourced answers. They run in the test suite, and you can run them here too.

Put this calculator on your site

Paste this where you want the calculator to appear. It is free to use, it stays in step with corrections made here, and the credit line below it links back so your readers can find the full version.

Height
Preview the embed

Keep the credit line. It is the only condition, and it is what keeps these calculators free.