Cron Parser

Detect syntax and predict run times

Loading tool…

About Cron Expression Parser

Cron Expression Parser names the dialect an expression belongs to — 5-field Unix, 6-field seconds-first, or 7-field Quartz — labels each field, and previews the next eight run times in a timezone you choose. The preview is the point: a cron expression takes seconds to write and minutes to read, and the only reliable check is a list of real dates.

Cron is not one language. Classic Unix cron has five fields and treats a restricted day-of-month together with a restricted day-of-week as an OR rather than an AND; Quartz puts seconds in front, adds a year at the end, and introduces ?, L, W and #; Spring's @Scheduled uses six fields that look like Quartz but number the weekdays the Unix way. Every expression is also evaluated in some timezone — the scheduler's, which is frequently not yours — and twice a year that timezone moves. Dialect, timezone and daylight saving are where nearly every cron bug lives; the syntax itself is rarely the problem.

How to use this developer tool

  1. Choose the format that matches your scheduler, or paste an expression and let the field count select it for you.
  2. Edit the whole expression in the single input, or box by box in the labelled field row below it. The two views stay in sync, and switching format carries over what you already filled in.
  3. Set the timezone to the zone the scheduler runs in, not the zone you are sitting in. Any IANA name is accepted.
  4. Read the detected syntax label before the dates. A six-field expression reported as ambiguous with Quartz contains no ?, L, W or #, so the tool cannot tell which dialect you meant.
  5. Scan all eight runs rather than the first. Each row gives wall-clock time in the selected zone, the same instant in ISO 8601, and how far away it is; look at a weekend and a month boundary.

Worked example: a weekday morning job

A Quartz six-field expression previewed in Asia/Shanghai, with the clock at Monday 21 September 2026, 10:00 — ten minutes after that day's run would already have fired.

Expression, timezone, reference time
0 0 9 ? * MON-FRI
Asia/Shanghai
2026-09-21T10:00:00+08:00
Next eight runs
1  Tue 2026-09-22 09:00:00   2026-09-22T01:00:00Z
2  Wed 2026-09-23 09:00:00   2026-09-23T01:00:00Z
3  Thu 2026-09-24 09:00:00   2026-09-24T01:00:00Z
4  Fri 2026-09-25 09:00:00   2026-09-25T01:00:00Z
5  Mon 2026-09-28 09:00:00   2026-09-28T01:00:00Z
6  Tue 2026-09-29 09:00:00   2026-09-29T01:00:00Z
7  Wed 2026-09-30 09:00:00   2026-09-30T01:00:00Z
8  Thu 2026-10-01 09:00:00   2026-10-01T01:00:00Z

Three facts appear here that the expression itself does not state. Monday the 21st is missing because 09:00 has already passed. The 26th and 27th are missing because they are a weekend. And every ISO instant is 01:00Z, because 09:00 in Asia/Shanghai is 01:00 UTC — so a scheduler that actually runs in UTC fires this job at 01:00 by its own clock.

Field order, and the symbols that shift meaning between dialects

Left to right, 5-field Unix is minute, hour, day-of-month, month, day-of-week. Quartz's six-field form puts seconds in front of that; its seven-field form adds a year at the end. A five-field expression is evaluated here with a seconds field of 0 prepended, so 0 9 * * 1 runs as 0 0 9 * * 1.

SymbolMeaningWorked example
*Every value the field allows* * * * * fires every minute
,A list of separate values0 9,13,17 * * * fires at 09:00, 13:00 and 17:00
-An inclusive range0 0 9 ? * MON-FRI fires 09:00 Monday through Friday
/A step, counted from the start of the range in front of it*/15 * * * * fires at minute 0, 15, 30 and 45
?Quartz only: no specific value, required in exactly one of day-of-month and day-of-week0 0 9 ? * MON-FRI leaves day-of-month unconstrained
LLast: last day of the month in day-of-month, last given weekday in day-of-week0 0 0 L * * fires 31 Jan, 28 Feb, 31 Mar; 0 0 0 * * FRIL fires the last Friday
WQuartz only: the nearest weekday to that day of the month15W in August 2026 fires Friday the 14th, because the 15th is a Saturday
#Quartz only: the nth given weekday of the month0 0 0 * * SAT#3 fires 17 Oct, 21 Nov and 19 Dec 2026

Troubleshooting

The job fires on days you never asked for.

Why it happens Classic Unix cron combines a restricted day-of-month with a restricted day-of-week using OR, not AND. Both fields being non-* means either one can trigger a run.

Fix Restrict only one of the two. 0 0 12 13 * FRI is not Friday the 13th — it fires every Friday and also the 13th of every month. For Friday the 13th, schedule 0 0 12 13 * * and check the weekday inside the job.

A run disappears or repeats once or twice a year.

Why it happens A daylight-saving transition. In America/New_York the local clock jumps from 02:00 to 03:00 on 8 March 2026, so 0 30 2 * * * has no 02:30 to fire at; on 1 November the hour from 01:00 repeats, so 01:30 exists twice.

Fix This preview resolves the skipped time to 03:30 local that day and lists the repeated time once. Real schedulers disagree — Vixie cron runs the missed job as the clock jumps, Quartz applies its misfire policy, some runners execute both passes. Schedule sensitive jobs in UTC, or outside 01:00 to 03:00 local.

A Quartz expression previews one day late.

Why it happens Quartz numbers the weekdays 1 = SUN through 7 = SAT. This preview evaluates numeric day-of-week the Unix way, 0 = SUN through 6 = SAT, with 7 also accepted as Sunday. Quartz's 6 is Friday; here it is Saturday.

Fix Write names instead of numbers. MON, FRI and MON-FRI mean the same thing in every dialect, which is what the extra characters buy you.

The preview is right but production fires at the wrong hour.

Why it happens The expression is evaluated in a timezone other than the one you previewed. A Kubernetes CronJob runs in UTC unless .spec.timeZone is set, a JVM scheduler uses the JVM default zone, and crond uses the system zone or CRON_TZ.

Fix Find the scheduler's zone, put that value in the timezone box, and re-read the preview. If the two lists differ, the schedule is wrong, not the tool.

When this tool is the right choice

  • Proving, before a deploy, that a schedule you just wrote fires on the days you meant.
  • Settling a code-review argument with eight concrete dates instead of a disagreement about field order.
  • Checking a schedule across a weekend, a month boundary and a leap day, where hand-verification quietly fails.
  • Comparing the same expression in two timezones by changing nothing but the timezone box.

When to use something else

  • Converting a previewed instant into another zone or a Unix timestamp. Copy the ISO value into the Date & Timestamp Converter.
  • Validating scheduler-specific extensions. Macros such as @daily, Quartz's L-3 and systemd's OnCalendar= are not cron expressions and are rejected here.
  • Knowing whether a job actually ran. Missed runs, overlapping executions, retries and misfire policies belong to the scheduler and to your monitoring.

Privacy and data handling

The expression is parsed and the run times computed inside this browser tab, using the timezone database the browser ships through Intl. Nothing is uploaded and nothing is kept between visits. Expressions are rarely sensitive, but the job names and incident notes people paste alongside them are, so trim the input down to the expression before sharing a screenshot.

Related developer tools

Frequently asked questions

Why does my expression fire on extra days?

Almost always because both day-of-month and day-of-week are restricted, which Unix cron treats as OR. Leave one of the two as * (or ? in Quartz) and the surprise goes away.

Which timezone does the preview use?

The one in the timezone box, resolved through the browser's own IANA database. It defaults to your local zone, which is convenient and also the most common source of a wrong answer, because schedulers rarely run where you do.

Is 0 9 * * 1 Monday or Sunday?

In the Unix numbering used here, 0 is Sunday and 1 is Monday, so it is 09:00 every Monday. In Quartz the same digit means Sunday, because Quartz starts its week at 1 = SUN. Writing MON removes the ambiguity in both.

Why is my six-field expression called ambiguous?

Six fields can be Quartz or a seconds-first Unix variant such as Spring's @Scheduled, and the two disagree on weekday numbering. With ?, L, W or # present it must be Quartz; without them the tool warns you instead of guessing.

Does the seven-field form honour the year?

Yes. The first six fields are evaluated normally and each candidate is then filtered against the year field, so 0 0 0 1 1 ? 2027-2029 previews three runs and stops. Lists, ranges and steps all work there.

What does a seconds field cost me?

Little in the expression and a lot in operations. A schedule such as 0/30 * * * * ? runs 2,880 times a day, and any job that occasionally exceeds its interval starts overlapping itself. Add a lock or a concurrency policy before shortening an interval.