Cron Expression Parser

Explain a cron expression in plain English and list the next runs

Runs entirely in your browser. Your data never leaves this device.

A 5-field Unix expression, or 6-7 fields for Quartz / Hangfire. Shorthands like @@daily also work.
Cron expression
Explanation and next runs

How to use it

  1. Paste a cron expression. The dialect is detected from the field count.
  2. Read the plain-English description and the next eight run times.
  3. The status bar warns you about the day-field trap described below.

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)
│ │ │ │ │
* * * * *

Quartz and Hangfire prepend a seconds field, so 0 30 9 * * MON-FRI means half past nine on weekdays, not "every 30 seconds in September". Misreading a six-field expression as five-field is a common and expensive mistake, which is why this parser reports which dialect it detected.

Four operators appear in every field: * for every value, , for a list, - for a range, and / for a step. 0 9-17/2 * * 1-5 is every two hours between 09:00 and 17:00, Monday to Friday.

The day-field trap

This is the one genuine surprise in cron, and it catches experienced people.

Day-of-month and day-of-week are joined with OR, not AND — but only when both are restricted. If one of them is *, the fields behave as you expect. If both name specific values, the job runs whenever either matches.

So 0 0 1 * MON does not mean "the first of the month, if it is a Monday". It means "every 1st of the month, and also every Monday". A job you thought ran twelve times a year runs about sixty-four.

This is behaviour inherited from the original Vixie cron and deliberately preserved by almost every implementation for compatibility. There is no operator to request AND. If you need "the first Monday of the month", you either use a Quartz extension (#) or check the date inside the job itself.

Time zones and daylight saving

The next-run times here are in your browser's zone. Your scheduler is probably in a different one, and that gap is where cron bugs come from.

Daylight saving makes it worse. When clocks jump forward, a job scheduled for 02:30 in an affected zone has no 02:30 to run at — most implementations skip it. When clocks go back, 02:30 happens twice, and some implementations run the job twice. Neither behaviour is standardised.

The reliable answer is to run schedulers in UTC and handle local presentation in the application. If a job genuinely must fire at local 09:00 year-round, use a scheduler with explicit time-zone support (Quartz.NET has it) rather than hoping the system zone does the right thing.

Reading the next runs

Listing actual future times is the fastest way to check an expression, because a description can be right while your intent was wrong. 0 0 * * 0 is correctly described as "at 00:00 on Sunday" — but if you wanted Monday, the list of dates makes that obvious in a way the sentence does not.

The parser searches forward up to four years. If nothing comes back, the expression can never match — 0 0 30 2 *, the 30th of February, is the classic example.

Frequently asked questions

What is the difference between Unix and Quartz cron?

Unix cron has five fields starting at minutes. Quartz — used by Quartz.NET and Hangfire — adds a leading seconds field, and optionally a trailing year, giving six or seven. Quartz also numbers day-of-week 1-7 with Sunday as 1, while Unix uses 0-6.

Why does my job run more often than I expect?

Most likely both day fields are set. When day-of-month and day-of-week are both restricted, standard cron matches if EITHER is satisfied, not both. `0 0 1 * MON` runs on the 1st and on every Monday.

What does */15 mean?

Every 15 units starting from the field's minimum. In the minutes field that is 0, 15, 30 and 45. Note it does not mean 'every 15 minutes from now' — it is aligned to the clock.

Which time zone do the next runs use?

Your browser's local zone, shown in the status bar. Servers usually run cron in UTC or the system zone, so confirm before trusting the times — this is the most common cause of a job firing an hour off after a DST change.

Can I use @daily and similar shorthands?

Yes. `@yearly`, `@monthly`, `@weekly`, `@daily`, `@midnight` and `@hourly` are expanded before parsing.

What about L, W and # ?

Those Quartz extensions — last day of month, nearest weekday, nth weekday — are not supported here. They have no equivalent in standard cron and are handled differently by each scheduler.

Related tools

browse category →

Last updated: