Cron Expression Generator

Write a cron expression in Unix, Spring or Quartz form, read what it actually means in English, and see the next ten fire times in UTC and your local time.

🔒 Your data never leaves your device🆓 Free🙅 No sign-up

crontab, Vixie/ISC cron, Kubernetes CronJob. Fields: minute hour day-of-month month day-of-week.

Supports `*`, lists, ranges, steps, month names (JAN–DEC), day names (SUN–SAT), macros like `@daily`.

At 09:30, Monday through Friday

⏭️ Next 10 runs

#UTCLocal timeIn
12026-01-01 09:30:0010h
22026-01-02 09:30:001d
32026-01-05 09:30:004d
42026-01-06 09:30:005d
52026-01-07 09:30:006d
62026-01-08 09:30:007d
72026-01-09 09:30:008d
82026-01-12 09:30:0011d
92026-01-13 09:30:0012d
102026-01-14 09:30:0013d

Local time appears once the page loads

🛠️ Builder

Pick a pattern, adjust the time, and the expression above updates.

0 9 * * *

🔄 Convert to other dialects

Spring0 30 9 * * 1-5
Quartz0 30 9 ? * 2-6
Unix uses OR between day-of-month and day-of-week; Spring and Quartz use AND. Only one field is restricted here, so the meaning is unchanged.

📚 Field reference

FieldAllowed valuesSpecial characters
minute0–59* , - /
hour0–23* , - /
day-of-month1–31* , - /
month1–12 or JAN–DEC* , - /
day-of-week0–7 (0 and 7 = Sunday) or SUN–SAT* , - /

✨ Macros

MacroEquivalentMeaning
@yearly / @annually0 0 1 1 *Once a year, 1 January at midnight
@monthly0 0 1 * *Midnight on the first of every month
@weekly0 0 * * 0Midnight every Sunday
@daily / @midnight0 0 * * *Every day at midnight
@hourly0 * * * *The top of every hour
@rebootOnce when cron starts (Unix only, no schedule)
🔒 Parsing and the fire-time search run entirely in your browser.

How to use the cron expression generator

  1. Choose your dialect: Unix for crontab and Kubernetes, Spring for a @Scheduled(cron = "…") annotation, Quartz for a Quartz or Spring Quartz trigger.
  2. Type an expression, or open the Builder and pick a pattern such as Weekdays at…, set the time, and press Use this expression.
  3. Read the plain-English line under the input — that is what the scheduler will actually do.
  4. Check the Next 10 runs table. It lists each fire time in UTC, in your browser’s local time, and how far away it is.
  5. Use the Convert panel to move the same schedule to another dialect, and read the notes: some conversions lose information.

Field layout by dialect

Dialect Fields Day-of-week numbering Notes
Unix min hour dom mon dow 0–7, both 0 and 7 are Sunday L and ? are rejected; @reboot exists
Spring sec min hour dom mon dow 0–7, both 0 and 7 are Sunday ? behaves like *; L is allowed in day-of-month
Quartz sec min hour dom mon dow [year] 1–7, Sunday is 1 one of day-of-month / day-of-week must be ?; year is optional

Every field accepts the same building blocks: * for “every value”, a list such as 1,15, a range such as MON-FRI, and a step such as */5 or 1-10/2. Month names JANDEC and day names SUNSAT work everywhere and are case-insensitive. Writing 5/10 means “start at 5, then every 10 up to the maximum”.

The OR rule that catches everyone

The single most misread part of cron is what happens when day-of-month and day-of-week are both restricted.

Vixie cron — the implementation behind virtually every Linux crontab — treats them as an OR. So 0 0 1 * MON fires at midnight on the 1st of every month and at midnight every Monday. Starting from 1 January 2026, the next three Unix fire times are 5, 12 and 19 January: every Monday, plus the 1st of each month.

Spring and Quartz treat the same pair as an AND. The Spring expression 0 0 0 1 * MON fires only when the 1st of the month is a Monday — 1 June 2026, then 1 February 2027. That is roughly seven times a year instead of sixty.

This tool models both behaviours, which is why switching the dialect changes the next-run list even when the expression text looks identical. When a Unix expression restricts both fields, converting it to Spring or Quartz is reported as impossible rather than silently producing a schedule that fires far less often.

Worked examples

Weekday stand-up reminder. 30 9 * * 1-5 reads as At 09:30, Monday through Friday. From Friday 2 January 2026 at 10:00 UTC, the next two fire times are Monday 5 January 09:30 and Tuesday 6 January 09:30 — the weekend is skipped.

Quarter-hourly polling. */15 * * * * is Every 15 minutes. Note that steps are anchored to the start of the range, so it fires at :00, :15, :30 and :45, not fifteen minutes after you deploy.

Month-end billing. 0 0 0 L * ? in Quartz is At 00:00, on the last day of the month. In 2026 that is 31 January, 28 February, 31 March, 30 April, and so on. Writing 0 0 31 * ? instead would silently skip February, April, June, September and November.

Leap-day job. 0 0 29 2 * fires only on 29 February. From January 2026 the next two runs are 2028-02-29 and 2032-02-29. The tool handles the century rule too: after 2096 the next leap-day run is 2104, because 2100 is not a leap year.

Half-minute health check. Spring’s */30 * * * * * is Every 30 seconds — impossible to express in Unix cron, which has no seconds field at all.

Tips and common mistakes

  • Steps are not offsets. A step always counts from the start of the range, never from “now”, and it does not wrap. */20 in the hour field gives 00:00 and 20:00 only — a 20-hour gap and then a 4-hour one, not an even three runs a day. Use 0,8,16 when you want even spacing.
  • Day 31 is not “month end”. Use L in Quartz or Spring, or schedule on day 1 of the next month and subtract a day in code.
  • Watch the seconds field. Pasting a five-field Unix expression into @Scheduled shifts every value one place left, so 0 2 * * * becomes “every minute of the second hour” instead of “02:00 daily”. The tool rejects the wrong field count outright.
  • Sunday is not a constant. It is 0 or 7 in Unix and Spring, but 1 in Quartz. Using names like SUN and MON-FRI sidesteps the whole problem.
  • Timezones and DST. Cron runs in the daemon’s timezone. A job scheduled at 02:30 local time is skipped on the spring-forward day and can run twice on the fall-back day. Scheduling in UTC avoids both, which is what Kubernetes CronJobs do by default.
  • Not yet supported here. Quartz’s # (nth weekday, such as 2#1 for the first Monday), 6L (last Friday of the month) and W (nearest weekday) are recognised and reported clearly rather than mis-parsed.

Glossary

  • Dialect – which cron implementation reads the expression: Unix, Spring or Quartz.
  • Field – one whitespace-separated part of the expression, such as the minute field.
  • Step – the /n suffix that takes every nth value from a range.
  • Macro – a shorthand like @daily that expands to a full expression.

Privacy

Nothing you type is sent anywhere. The parser, the English description and the fire-time search all run as JavaScript in your browser tab, so an internal schedule or a hostname embedded in a comment never leaves your device.

Frequently asked questions

What is the difference between Unix, Spring and Quartz cron?

Unix cron uses five fields starting at minutes. Spring's @Scheduled adds a seconds field at the front, making six. Quartz also starts with seconds but numbers days of the week 1-7 with Sunday as 1, allows an optional year field at the end, and requires a question mark in either day-of-month or day-of-week.

Why does Quartz require a question mark?

Because day-of-month and day-of-week both select days, and Quartz refuses to guess how to combine them. You set one field and write a question mark in the other to say "no value specified here".

Does 0 0 1 * MON run on the 1st, on Mondays, or only on Mondays that fall on the 1st?

In Unix cron it runs on both — when either field is restricted, the schedule fires if day-of-month OR day-of-week matches. Spring and Quartz use AND instead, which is why this tool shows a different next-run list depending on the dialect you pick.

What does the L character do?

In the day-of-month field, L means the last day of the month, so it lands on the 31st in January, the 28th in a normal February and the 29th in a leap year. It is a Quartz and Spring extension; standard Unix crontab rejects it.

What timezone does cron use?

The daemon's timezone, which is usually the server's. This tool shows every fire time in both UTC and your browser's local timezone so you can see the gap. Kubernetes CronJobs default to UTC, and Quartz lets you set a timezone on the trigger.

What does @reboot mean?

It is a Vixie cron extension that runs the job once when the cron daemon starts, typically at boot. It has no schedule at all, so there is no next fire time to calculate, and neither Spring nor Quartz supports it.

Related tools

Last reviewed: