Cron Expression Generator
Five fields in, a crontab line plus a plain-English reading and the next five runs out.
The crontab line — crontab.txt
The fields, in the order the file writes them
| Field | Accepts | Worth knowing |
|---|---|---|
| minute | 0-59 | Never leave this at * unless you mean every single minute. */5 is the smallest interval most shared hosts will honour reliably. |
| hour | 0-23 | Server time, not yours. A job set for 02:00 on a UTC box runs at 04:00 in Warsaw in summer, which matters for anything tied to a business day. |
| day of month | 1-31 | Setting 29, 30 or 31 means the job silently skips the months that are shorter. There is no cron syntax for "last day of the month". |
| month | 1-12 or JAN-DEC | Names are case-insensitive and cannot take steps in every implementation, so prefer numbers when the schedule is unusual. |
| day of week | 0-7 or SUN-SAT | Both 0 and 7 are Sunday. Combined with a day-of-month other than *, the job runs when EITHER matches -- the rule this tool warns about. |
About this generator
Set the five cron fields and get a crontab line, a sentence describing what it means, and the next five times it will actually fire. The parser follows Vixie cron - the one on Linux and macOS - including the rule that trips almost everyone: when both day-of-month and day-of-week are set, the job runs when either matches, not both.
The five fields, and the trap in the last two
The fields are minute, hour, day-of-month, month, day-of-week, and each takes a value, a list (1,15), a range (9-17), a step (*/15) or a range with a step (9-17/2). So far so predictable.
Then there is the rule nobody expects: if day-of-month and day-of-week are both set to something other than *, cron runs the job when EITHER matches. "0 0 1 * MON" is not "the first of the month, if it is a Monday" - it is "the first of every month, and also every Monday". That is roughly five times as many runs as intended, and this tool warns you whenever your expression is in that state.
Why the job works by hand and fails from cron
Almost always the environment. Cron runs with a nearly empty PATH, no shell profile, and HOME possibly unset. A command that works in your SSH session fails because "php" is not on the path, or because a relative path resolved against a different working directory. Use absolute paths for both the interpreter and the script, every time.
The other half is output. If a cron job prints anything and you have not redirected it, cron tries to email the crontab owner - and on a box with no mail transport that output vanishes along with your error messages. Redirect to a log file while you are debugging, and only discard output once the job is known good.
Things people ask about cron
What timezone does cron use?
The server's, not yours. The next-run times shown here are in your browser's local time because that is all a web page can know. Check the server with date over SSH before you rely on an overnight window - a host in UTC and a developer in Europe are two hours apart in summer.
Can I use @daily or @reboot instead?
Yes. Vixie cron accepts @yearly, @monthly, @weekly, @daily, @hourly and @reboot in place of the five fields. @daily is exactly "0 0 * * *". They read well, but they hide the actual time, which is why explicit fields are better when several jobs must not collide - and @reboot is not a schedule at all, it fires once when cron starts.
What about L, W, # and ?
Those are Quartz extensions, from the Java scheduler, and also what most "cron generator" pages emit. Unix crontab does not understand them: "last day of the month" has no cron syntax. The usual workaround is to run daily and exit early unless date +%d-tomorrow is 01. This tool rejects them rather than generating a line that silently never fires.
How do I stop two runs overlapping?
Use a lock. flock is the least effort: flock -n /tmp/task.lock /usr/bin/php task.php exits immediately if the previous run is still going. Without it, an every-minute job that sometimes takes 90 seconds will eventually have a dozen copies fighting over the same database rows.
Jobs that tend to be scheduled
-
The renewal that runs and still expires
Certificate renewal is the most common cron job there is, and the most common one to fail silently.
The expression and its next run times are worked out in this tab. Nothing about your schedule leaves the browser.