-- fields are read as UTC, the way cron, GitHub Actions and Vercel do --
- minute
- at 0
- hour
- at 9
- day of month
- every value
- month
- every value
- day of week
- at 1, 2, 3, 4, 5
How to use it
Type a five-field expression. The tool validates each field, points at the one that is wrong when there is one, and computes the next five runs.
The five fields
┌───────────── minute (0-59)
│ ┌─────────── hour (0-23)
│ │ ┌───────── day of month (1-31)
│ │ │ ┌─────── month (1-12 or JAN-DEC)
│ │ │ │ ┌───── day of week (0-6 or SUN-SAT, 0 = Sunday)
│ │ │ │ │
* * * * *
| Syntax | Meaning |
|---|---|
* | every value |
5 | only 5 |
1-5 | 1 through 5 inclusive |
*/15 | every 15 units, starting at the minimum |
5/10 | from 5 onwards, then every 10 |
1,15,30 | exactly these values |
7 is accepted as an alias for Sunday alongside 0: crontab(5) documents it
explicitly.
The day-of-month and day-of-week trap
This is the source of cron bugs. When both day fields are restricted — neither
is * — cron fires as soon as either one matches, not when both do.
0 0 1 * 1
It reads naturally as "the first Monday of the month". In reality: every Monday, plus the 1st of every month. To get an actual first Monday you have to test the date inside the script:
# 1st Monday of the month: cron fires every Monday, the script filters
0 0 * * 1 [ "$(date +%d)" -le 07 ] && /usr/local/bin/my-scriptAs soon as only one of the two fields is restricted, the rule becomes intuitive
again: 0 9 * * 1-5 does mean "at 9am, Monday to Friday".
Time zone
This tool reads the fields as UTC, the way system cron, GitHub Actions and Vercel do. A scheduler that reads them in local time raises two questions with no good answer: when clocks spring forward, a task at 02:30 does not exist; when they fall back, it exists twice.
Hence a simple rule: schedule in UTC and convert for display. A task at 9am
Paris time is 0 8 * * * in winter and 0 7 * * * in summer — or, better, is
scheduled at an hour where the offset does not matter.
Valid expressions that never fire
0 0 30 2 *
The 30th of February is syntactically correct and will never happen. The tool detects it and says so, instead of searching forever.
0 0 29 2 * is subtler: it does fire, but only in leap years — so once every four
years.
Checking a cron in a project
// GitHub Actions: exact minutes are discouraged, the scheduler is
// congested at :00 and can drift by several minutes
on:
schedule:
- cron: "17 3 * * *" // rather than "0 3 * * *"A GitHub Actions cron is not guaranteed to the minute: it is a shared queue. For a task that genuinely has to start on time, you need a dedicated scheduler.
topics covered
related reading
- Case ConverterutilsConvert text to camelCase, snake_case, kebab-case and seven other formats, line by line1 shared tag(s): texte
- Dates and TimestampsutilsConvert a Unix timestamp into a readable date, both ways and across seven time zones1 shared tag(s): texte
- Regex TesterutilsTest a pattern, see highlighted matches, captured groups and the result of a replacement1 shared tag(s): texte