HomeText & Developer Tools › Cron Expression Parser

Cron Expression Parser

Paste a cron expression to get a plain-English description and the next five times it will fire in your local time zone, with a table of common patterns.

The five cron fields

A crontab line schedules a job with five space-separated fields, in this order: minute (0-59), hour (0-23, 24-hour clock), day of month (1-31), month (1-12 or JAN-DEC) and day of week (0-7 or SUN-SAT, where both 0 and 7 mean Sunday). Some schedulers - Quartz, Spring, and many container platforms - accept a sixth field at the front for seconds. This parser accepts either form and tells you which one it saw.

Every field supports four operators. An asterisk * means every value. A comma lists values: 1,15. A hyphen gives a range: 9-17. A slash gives a step: */15 in the minute field means 0, 15, 30 and 45, and 0-30/10 means 0, 10, 20 and 30. Ranges and steps combine, so 2-10/3 is 2, 5, 8. Cron does not sleep between runs; it wakes every minute and fires any job whose fields all match the current time.

The day-of-month and weekday trap

The one rule that surprises almost everyone is how the two day fields interact. If both day of month and day of week are restricted, cron runs the job when either matches, not both. So 0 0 1 * 1 fires on the first of every month and on every Monday, which is usually not what the author meant. If exactly one of the two is *, only the other one applies, which is the normal case. To get "the first Monday of the month" you need a day-of-month range plus a weekday, like 0 0 1-7 * 1, which this parser handles correctly.

Worth knowing too: 0 9 * * 1-5 reads as 9:00 AM Monday through Friday, and that is the most common business schedule in crontabs. */15 * * * * fires at :00, :15, :30 and :45 of every hour, 96 times a day. A step never wraps past the end of a range, so */40 in the minute field fires at :00 and :40 only, skipping the 20-minute remainder at the top of the next hour.

Time zones, environment and testing

The preview above uses your computer's local time zone. Real cron uses the daemon's time zone, which on most Linux servers and in most Docker images is UTC. If your job must run at 9:00 AM Eastern, either set CRON_TZ=America/New_York at the top of the crontab (supported by Vixie cron and cronie) or convert the hour yourself and remember that daylight saving time shifts it twice a year. Jobs scheduled inside the hour that a spring-forward skips may not run at all; jobs inside a fall-back hour may run twice.

Two more practical notes. Cron runs with a minimal environment - typically only HOME, PATH=/usr/bin:/bin, SHELL and LOGNAME - so always use absolute paths to binaries and source any profile your script needs. And a percent sign in a crontab command is special: it becomes a newline unless you escape it as \%, which bites people writing date +%Y-%m-%d in a cron line. Test with crontab -l, and check /var/log/syslog or journalctl -u cron to confirm the job actually fired.

Frequently asked questions

What is the difference between 0 and 7 in the weekday field?

Nothing - both mean Sunday. Cron accepts 0-7 so that a range like 1-7 covers Monday through Sunday. This parser normalizes 7 to 0 before matching.

Why does my job run twice as often as I expect?

Usually because both the day-of-month and day-of-week fields are set. Cron ORs them together, so the job fires on either condition. Set one of them to * unless you really want both.

Does cron support @daily and @reboot?

Yes, as shorthand: @yearly, @monthly, @weekly, @daily (or @midnight), @hourly and @reboot. They are not part of the five-field syntax, so paste the expanded form here - @daily is 0 0 * * *.

Are the next run times exact?

They are exact for the fields you gave, in your local time zone, ignoring daylight saving transitions and assuming the machine is awake. Your server's clock and time zone decide the real firing times.