Cron Expression Explainer

Paste a cron expression and get a plain-English description, a field-by-field breakdown, and the next ten run times in the time zone of your choice, with daylight saving handled.

In plain English

At 09:30, Monday through Friday

Field by field

FieldYou wroteMeaningMatches
Minute30minute 3030
Hour9hour 99
Day of month*every day1, 2, 3, 4, 5, 6, ... 31 (31 values)
Month*every monthJan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
Day of week1-5day of the weeks Monday through FridayMon, Tue, Wed, Thu, Fri

Next 10 runs

Times are calculated for the selected zone, including daylight saving changes. Your server's cron uses the system time zone (or CRON_TZ where supported), which may not be this one.

Runs entirely in your browser. Nothing you type or upload is sent to a server.

How to read a cron expression

A standard cron expression is five fields separated by spaces. Reading left to right they are the minute, the hour, the day of the month, the month, and the day of the week. The job runs at every moment where all five fields match, with one exception covered below. A field can be a number, a star, or a more elaborate pattern.

FieldAllowed valuesNotes
Minute0 to 59
Hour0 to 2324-hour clock, so 17 is 5 PM
Day of month1 to 31Days a month does not have are simply skipped
Month1 to 12, or JAN to DECNames are case-insensitive
Day of week0 to 7, or SUN to SAT0 and 7 are both Sunday

The four building blocks

Every field is made from the same four pieces, which you can combine with commas. A star means every value. A comma makes a list, so 1,15 means 1 and 15. A dash makes a range, so 9-17 means 9 through 17 inclusive. A slash makes a step: */15 means every 15th value across the whole range,10-40/10 means 10, 20, 30 and 40, and 5/10 means 5, 15, 25 and so on to the end of the range. Lists can mix them, for example 0-10/5,30.

The classic trap with steps is that they restart at the top of each unit. */45 in the minute field does not mean every 45 minutes. It means minutes 0 and 45 of every hour, so the gaps are 45 and 15 minutes alternately. The same applies to */5 in the hour field, which fires at 0, 5, 10, 15 and 20, then again at midnight, four hours later. If a step does not divide the range evenly, the schedule is uneven, and this tool lists the exact times so you can see it.

The day-of-month and day-of-week rule

If both day fields are restricted, cron runs the job when either matches. Every other pair of fields works as AND.

This is the most misunderstood behavior in cron, and it is documented in the crontab manual: when the day of month and day of week both begin with something other than a star, the command runs when either field matches. So 0 0 13 * 5 does not mean Friday the 13th. It means midnight on the 13th of every month and midnight on every Friday. If either field starts with a star, even as a step like */2, the OR rule is switched off and the two fields combine normally. The explainer above shows a warning whenever the OR rule applies to your expression.

Shortcuts and @reboot

Most crons accept @hourly, @daily (also @midnight), @weekly, @monthly and @yearly (also @annually). Each is fixed shorthand: @weekly is 0 0 * * 0, midnight at the start of Sunday. @reboot is different. It has no schedule at all and runs when the cron daemon starts at boot. It is useful for starting a background process. Implementations differ on whether it fires again when the daemon is restarted without a reboot: cronie and Debian's cron deliberately skip it, older Vixie cron runs it again.

Time zones and daylight saving

Cron has no idea what time zone you meant. It uses the clock of the machine, so a schedule that says 09:00 means 09:00 on that machine. Most servers run in UTC, which does not change with the seasons. A server set to a local zone does, and that creates two awkward days a year in zones that observe daylight saving.

On the spring-forward day, a clock time such as 02:30 does not exist. On the fall-back day, 01:30 happens twice. Vixie-derived cron implementations handle this with a special rule: a job at a fixed time that was skipped is run when the clock jumps, a fixed-time job in the repeated hour runs once, and a job with a wildcard minute or hour, like */30, simply follows elapsed time. The explainer follows those rules and flags the affected rows. Other schedulers behave differently, and some skip the job entirely, so the safe practice is to avoid the hours between 01:00 and 03:00 for anything important, or to run the server in UTC.

Quartz, Spring and AWS are different

If you copied an expression from a Java project, a Spring @Scheduled annotation, a Quartz trigger or an AWS EventBridge rule, it probably has six or seven fields and may contain ?, L, W or #. Those characters mean "no specific value", "last", "nearest weekday" and "nth weekday of the month", and standard crontab does not understand them. Putting them in a crontab file produces an error or, worse, a schedule you did not intend. This tool recognizes them and tells you so rather than guessing. See the JSON tool and the JWT decoder for other developer helpers on this site.

Habits that prevent surprises

Test the schedule before relying on it, and check the next several run times rather than only the first. Avoid minute 0 when many jobs share a server, because everyone else schedules on the hour. Use absolute paths in the command, since cron runs with a minimal environment. Redirect output to a log file, or you will only learn the job failed when someone notices. And remember that cron does not catch up: if the machine is off at the scheduled moment, the run is lost, which is the one thing a tool like anacron exists to fix.

Frequently Asked Questions

It means every 5 minutes. The first field is the minute, and */5 is a step over the whole range 0 to 59, so the job runs at minutes 0, 5, 10 and so on up to 55, every hour of every day.
Minute (0 to 59), hour (0 to 23), day of month (1 to 31), month (1 to 12 or JAN to DEC), and day of week (0 to 7 or SUN to SAT, where both 0 and 7 mean Sunday).
If you set both the day of month and the day of week, standard cron runs the job when either one matches. 0 0 13 * 5 runs on every 13th and on every Friday. To run only on Friday the 13th, schedule it every Friday and check the date inside the script.
Standard cron has no last-day syntax. Run the job daily and have the script exit unless tomorrow is the 1st, for example with [ "$(date -d tomorrow +%d)" = "01" ] in a shell. Quartz and Spring support L in the day-of-month field, but crontab does not.
There is none. Both mean Sunday. Most crons accept 0 to 7 so that 1-7 reads naturally as Monday through Sunday, and 5-7 means Friday through Sunday.
That is a different dialect. Quartz and Spring add a leading seconds field, Quartz allows a trailing year, and AWS EventBridge uses six fields ending in a year. Standard crontab uses exactly five fields, which is what this tool explains.
The system time zone of the machine running the daemon, unless the cron implementation supports CRON_TZ. Cloud servers are usually set to UTC. Managed schedulers such as GitHub Actions run in UTC with no option to change it. Use the zone selector above to see what a schedule means in a particular zone.
It depends on the daemon. Vixie-derived cron runs a fixed-time job that was skipped when the clocks jump forward, and runs a fixed-time job once when an hour repeats. Wildcard jobs such as */30 follow elapsed time. Other schedulers may skip or repeat jobs. Scheduling at a time that is never ambiguous, such as 10:00, avoids the question.
The Internet Omni-Tool