CODDY Tool

Cron Expression Generator

Build, check and understand cron schedules, with the next run times.

Write a cron expression and see it described in plain English along with when it will actually fire. Catches the day-of-month and day-of-week trap that makes jobs run far more often than intended.

Everything you enter stays in this browser tab. Nothing is sent to our servers, logged or stored.

Loading tool…

About Cron Expression Generator

A cron expression is five fields — minute, hour, day of month, month, day of week — and its reputation for being unreadable is mostly earned. The fields are positional with no labels, the ranges differ between them, and one rule behaves the opposite of how it reads.

That rule is worth stating plainly, because it causes real incidents. When both the day-of-month and the day-of-week field are restricted, cron runs when **either** matches, not when both do. So `0 0 1 * 1` does not mean “the 1st of the month, if it is a Monday” — it means “the 1st of the month, and also every Monday”, which fires around five times as often. When either field is `*` the behaviour is the intuitive one, which is exactly why the bug hides until someone sets both.

This tool spells that out in the description, warns when the rule is in play, and — more usefully than either — shows you the next six times the expression will actually fire. A list of real dates settles an argument that reading the syntax cannot.

The description and the schedule come from the same parse, deliberately. A tool that describes an expression with one code path and computes run times with another will eventually disagree with itself, and the person trusting the description is the one who gets paged.

How to build a cron expression

  1. Start from a common schedule

    Hourly, daily, weekdays at 9am. Most real jobs are a small edit away from one of these.

  2. Edit the fields

    Each field is labelled under the box with its valid range, so you can see which position you are changing.

  3. Read the description

    Plain English, including an explicit warning when the day fields are being ORed.

  4. Check the next runs

    Six real dates and times. If they are not what you expected, the expression is wrong regardless of how it reads.

The syntax, in full

  • * — every value in the field.
  • 5 — exactly that value.
  • 1-5 — an inclusive range.
  • 1,3,5 — a list.
  • */15 — every 15th value, starting at the field's minimum.
  • 9-17/2 — every 2nd value within a range.
  • JAN–DEC and SUN–SAT — names, accepted in the month and day-of-week fields.
  • @daily, @hourly, @weekly, @monthly, @yearly — shorthands every implementation accepts.

Things that catch people out

  • Both day fields set means OR, not AND. This is the big one.
  • Sunday is both 0 and 7. Either works, and mixing them in one list is legal but confusing.
  • Six fields is not standard cron. Quartz and systemd add a seconds field at the front; pasting one into crontab fails.
  • Cron uses the server's time zone, usually UTC. A job set for 09:00 will not run at 09:00 your time unless the machine agrees.
  • */7 does not mean “every 7 minutes” across the hour boundary. It fires at 0, 7, 14 … 56, then again at 0 — a 4-minute gap at the top of every hour.
  • A valid expression can still never fire. 30 February parses perfectly and never happens.

Frequently asked questions

Why does my job run more often than the expression says?

Almost certainly the day-field OR rule. If you have set both day-of-month and day-of-week to something other than *, cron fires when either matches. "0 0 1 * 1" runs on the 1st and on every Monday, not only on Mondays that fall on the 1st.

How do I run something on the 1st only if it is a Monday?

You cannot, in cron alone — the syntax has no AND for the two day fields. Schedule it for every Monday and check the day of the month inside the script, exiting early when it does not match.

What time zone do the next runs use?

Your browser's, so the dates are readable. Cron on a server uses that machine's time zone, which is very often UTC. That mismatch is the single most common reason a job fires at an unexpected hour.

Why was my six-field expression rejected?

Standard cron has five fields. Quartz, Spring and systemd timers add a seconds field at the front, so a six-field expression from documentation for those will not work in crontab. Drop the leading field.

Does */7 mean every 7 minutes?

Not quite. Steps restart at the top of each hour, so it fires at 0, 7, 14 … 56 and then 0 again — a 4-minute gap once an hour. For a genuinely even interval that does not divide 60, use a scheduler with real intervals rather than cron.

All Developer Tools

Cron Expression Generator is free to use with no account, no watermark and no usage limits. Last updated 14 August 2026.