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.
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`.
⏭️ Next 10 runs
| # | UTC | Local time | In |
|---|---|---|---|
| 1 | 2026-01-01 09:30:00 | — | 10h |
| 2 | 2026-01-02 09:30:00 | — | 1d |
| 3 | 2026-01-05 09:30:00 | — | 4d |
| 4 | 2026-01-06 09:30:00 | — | 5d |
| 5 | 2026-01-07 09:30:00 | — | 6d |
| 6 | 2026-01-08 09:30:00 | — | 7d |
| 7 | 2026-01-09 09:30:00 | — | 8d |
| 8 | 2026-01-12 09:30:00 | — | 11d |
| 9 | 2026-01-13 09:30:00 | — | 12d |
| 10 | 2026-01-14 09:30:00 | — | 13d |
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
0 30 9 * * 1-50 30 9 ? * 2-6📚 Field reference
| Field | Allowed values | Special characters |
|---|---|---|
| minute | 0–59 | * , - / |
| hour | 0–23 | * , - / |
| day-of-month | 1–31 | * , - / |
| month | 1–12 or JAN–DEC | * , - / |
| day-of-week | 0–7 (0 and 7 = Sunday) or SUN–SAT | * , - / |
✨ Macros
| Macro | Equivalent | Meaning |
|---|---|---|
| @yearly / @annually | 0 0 1 1 * | Once a year, 1 January at midnight |
| @monthly | 0 0 1 * * | Midnight on the first of every month |
| @weekly | 0 0 * * 0 | Midnight every Sunday |
| @daily / @midnight | 0 0 * * * | Every day at midnight |
| @hourly | 0 * * * * | The top of every hour |
| @reboot | — | Once when cron starts (Unix only, no schedule) |
How to use the cron expression generator
- Choose your dialect: Unix for crontab and Kubernetes, Spring for a
@Scheduled(cron = "…")annotation, Quartz for a Quartz or Spring Quartz trigger. - Type an expression, or open the Builder and pick a pattern such as Weekdays at…, set the time, and press Use this expression.
- Read the plain-English line under the input — that is what the scheduler will actually do.
- 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.
- 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 JAN–DEC and day names SUN–SAT 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.
*/20in 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. Use0,8,16when you want even spacing. - Day 31 is not “month end”. Use
Lin 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
@Scheduledshifts every value one place left, so0 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
SUNandMON-FRIsidesteps 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 as2#1for the first Monday),6L(last Friday of the month) andW(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
/nsuffix that takes every nth value from a range. - Macro – a shorthand like
@dailythat 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
- Unix Timestamp ConverterA live epoch clock, instant timestamp-to-date conversion in UTC and your local time, a date-to-timestamp direction, and a batch mode for whole log columns.
- JSON Formatter & ValidatorPaste JSON, get it beautified, minified or validated with the exact line and column of the problem. Everything runs in your browser.
- Base64 Encoder & DecoderConvert text, files and data URIs to and from Base64 with correct UTF-8 handling, a URL-safe option and MIME line wrapping. Nothing is uploaded.
- Password GeneratorBuild a random password or a memorable passphrase with real cryptographic randomness. Entropy, strength and crack time are shown for the exact options you picked — and nothing ever leaves your browser.
- UUID GeneratorCreate random or time-ordered identifiers in bulk, format them for JSON, CSV or a SQL insert, and paste any existing id to find out which version it is and when it was made.
- Hash GeneratorCompute SHA and CRC32 digests of text or files entirely in your browser, switch between hex and Base64, sign messages with HMAC, and check two hashes against each other.
Last reviewed: