Cron expression explainer
Read a cron expression in plain language, see its next runs in any time zone, and tidy it into its standard form.
Code examples
Copy and paste these into your own project. Each one uses only the language's standard library, so there is nothing to install.
const expand = (field, min, max) =>
field.split(',').flatMap((part) => {
const [range, step = '1'] = part.split('/')
const [from, to = from] = range === '*' ? [min, max] : range.split('-').map(Number)
return Array.from({ length: Math.floor((to - from) / Number(step)) + 1 }, (_, i) => from + i * Number(step))
})
function matches(expression, instant) {
const [minute, hour, dayOfMonth, month, dayOfWeek] = expression.split(' ')
const inMonth = expand(dayOfMonth, 1, 31).includes(instant.getUTCDate())
const inWeek = expand(dayOfWeek, 0, 7).some((day) => day % 7 === instant.getUTCDay())
const dayMatches =
!dayOfMonth.startsWith('*') && !dayOfWeek.startsWith('*') ? inMonth || inWeek : inMonth && inWeek
return (
expand(minute, 0, 59).includes(instant.getUTCMinutes()) &&
expand(hour, 0, 23).includes(instant.getUTCHours()) &&
expand(month, 1, 12).includes(instant.getUTCMonth() + 1) &&
dayMatches
)
}
console.log(matches('*/15 9-17 * * 1-5', new Date('2023-11-14T09:30:00Z')))What it does
Read a cron expression in plain language, see when it runs next in any time zone, and tidy it into its canonical form. It handles standard five-field cron and the Quartz or Spring dialect with seconds. Everything is worked out in your browser.
How to use it
- Type or paste an expression, such as
*/15 9-17 * * MON-FRI. Shortcuts like@dailyand@hourlyare understood. The field your cursor is in is highlighted and explained below. - Choose the dialect: Standard (five fields) or Quartz / Spring (six or seven, starting with seconds).
- Choose the time zone to read the schedule in, and how many upcoming runs to list.
- Read the description in words above the input, with the next run times below it. Warnings point out syntax that not every cron understands.
- Press Random or a schedule chip for a starting point, or switch to Several lines to check one expression per line.
Examples
@daily → 0 0 * * *
*/15 9-17 * * MON-FRI → Every 15 minutes, between 09:00 AM and 05:59 PM, Monday through Friday
A Quartz expression for noon on the second Monday of every month:
0 0 12 ? * MON#2
Good to know
- The five fields are minute, hour, day of the month, month and day of the week.
- Standard cron counts Sunday as 0. Quartz and Spring count it as 1 and need a
?in either the day-of-month or the day-of-week field. - Cron runs by the clock of the machine or scheduler it lives on, so pick that time zone, often UTC.
- Quartz
L,Wand#(last day, nearest weekday, nth weekday) are supported. - A field that can’t be read turns red, and the message names it.
- With both a day of the month and a day of the week, the job runs when either matches, not only when both do.
@reboothas no schedule to list, and7as Sunday or the Quartz characters?,L,Wand#in standard cron are flagged.
What is a cron expression?
A cron expression says when a job should run, in five fields: minute, hour, day of the month, month and day of the week. * means every value, */15 every 15th, 1-5 a range and 1,15 a list. Quartz and Spring add a seconds field in front and sometimes a year at the end, and support extras such as L, W and #.
Frequently asked questions
Which time zone do the runs use?
The one you choose. Cron runs by the clock of the machine or scheduler it lives on, so pick that zone, often UTC, to see the real run times.
What is the difference between standard and Quartz?
Standard cron has five fields and counts Sunday as 0. Quartz and Spring have six or seven, start with seconds, count Sunday as 1 and need a ? in either the day-of-month or the day-of-week field.
Does this tool send my expressions anywhere?
No. The explanation and the run times are worked out in your browser. What you type is never sent to our servers.