Apex Automation free tools
Cron Expression Generator
A generator, a builder and a reader, including the two days a year your job runs twice or not at all
Reading a cron expression is the easy half. The half that wakes somebody at four in the morning is the clock: a nightly job that silently skips a day in spring, runs twice in autumn, or fires on every Monday as well as the first of the month because of a rule nobody remembers. This page shows the next runs in your own timezone and in UTC, side by side, and marks every run the clocks delete or repeat.
- Free to use
- No account needed
- Nothing uploaded
- Six dialects
What this page will read
- Five, six or seven fieldsFive for crontab, Kubernetes and GitHub Actions. Six for Spring and EventBridge. Six or seven for Quartz, with seconds at the front and an optional year at the end.
- Stars, lists, ranges and steps*, 1,15, 1-5 and */5, and a step on a range such as 10-30/10, which counts from the start of the range rather than from zero.
- Names in either caseJAN to DEC and SUN to SAT, written however you like. A range that wraps, such as FRI-MON, is read as wrapping.
- The Quartz extrasL for the last day, L-3 for three days before it, LW for the last weekday, 15W for the weekday nearest the 15th, 6#3 for the third Friday, 2L for the last Monday, and ? for the day field you are not using.
- Nicknames@daily, @hourly, @weekly, @monthly and @yearly, in the dialects that accept them. GitHub Actions does not, and the page says so rather than guessing.
- Every timezone the browser knowsNot a short list of capitals. The whole IANA set, read from the database the browser already ships with.
- Several expressions at oncePaste a list and the page finds the moments where more than one of them starts.
- Any moment you want checkedGive a date and a time and every field is checked against it, so you can see which one failed.
What will not work. @reboot has no schedule to show, because it fires once when the machine starts. A seconds field in a dialect that has none is reported rather than quietly dropped. And an expression that can never match, such as 30 February, is read correctly and then has no runs to show, which is the honest answer rather than an error.
The two days a year that break nightly jobs
Most cron tools show you the next runs as a list of times and stop there. That is fine for 364 days of the year. On the other two, the list is wrong in a way that looks exactly like it is right.
When the clocks go forward, an hour of the day does not happen. In New York the morning of 8 March 2026 goes from 01:59 to 03:00. A job set for 02:30 has no 02:30 to run at, so it does not run. Nothing errors, nothing is logged, and the next morning everything looks normal again. The page lists that run under the table rather than leaving a silent hole in it.
When the clocks go back, an hour happens twice. The morning of 1 November 2026 has two 01:30s in New York, one at 05:30 UTC and one at 06:30 UTC. Unix cron, Kubernetes and EventBridge Scheduler run the job on the first one. A scheduler that wakes up and reads the wall clock can run it on both, which is how a billing run charges everybody twice, once a year, in a way nobody reproduces in testing.
What is claimed here, and what is not. This page does not promise that your scheduler behaves the way it should. It promises something narrower and checkable: the run times shown are the ones the expression describes in the zone you chose, worked out from the timezone database your own browser ships with, and every run that the clocks delete or repeat is named. Which of the two repeated runs your scheduler picks is a property of that scheduler, and the page says what each one documents rather than guessing.
The day rule that catches almost everybody
Write 0 0 1 * 1 and most people read it as "midnight on the first of
the month, if that is a Monday". It is not. POSIX cron says that when both the
day-of-month and the day-of-week fields are restricted, a run happens when
either one matches. So that expression runs on the first of every month,
and on every Monday, which is about five times as often as intended.
The rule only applies when both fields are restricted. If one of them is a star, the other decides on its own. Quartz and EventBridge sidestep the whole question by insisting that one of the two is a question mark, which is why converting an expression like that cannot be done honestly and the page says so instead of producing something that looks fine.
Six dialects that look identical and are not
The same five numbers mean different things depending on what is reading them. The differences are small, undocumented in most tools, and each one has its own way of going wrong:
- Sunday is 0, or 1Unix, Kubernetes, GitHub Actions and Spring count Sunday as 0. Quartz and EventBridge count it as 1. The same number means a different day, and nothing complains.
- Seconds at the frontQuartz and Spring put seconds first, so a five field expression pasted into either one is read with everything shifted by a field.
- A year at the endEventBridge requires one, Quartz allows one. Dropping it turns a one off into something that repeats every year.
- The question markQuartz and EventBridge require exactly one of the two day fields to be a question mark. Kubernetes accepts one and treats it as a star. Unix and GitHub Actions reject it.
- Five minutes, not oneGitHub Actions will not run a workflow more often than every five minutes. A faster expression is valid, commits cleanly, and then does not do what it says.
- Where the time comes fromKubernetes reads UTC unless spec.timeZone is set. GitHub Actions reads UTC unless the timezone field is set, which arrived in March 2026. Quartz uses the JVM default. Plain crontab uses the machine's own clock.
Converting between them is where schedules quietly change meaning, so every conversion on this page carries its own warnings: what was dropped, what was renumbered, and what the target dialect simply cannot express.
What has actually been tested
Every figure here is a test run that has to pass before anything reaches this page. If one fails, nothing ships. A number on a page that nothing checks goes stale, so a test reads this page, pulls out every figure in it, and compares each one with the code behind it.
- 30Every file that ships, scanned for generated copy, inline styles, off-origin loads and broken asset paths ship
- 22The live page in a real browser, under the security policy it ships with e2e
- 23Answers written out by hand from the specifications, not produced by this code semantics
- 15Every error the parser can give, and the field it names parse
- 15Layout at seven screen sizes, with the browser text enlarged, and the contrast of every line visual
- 13Every dialect written into every other, and what each conversion loses convert
- 13Input nobody would type: 400 values in one field, every zone at once, schedules that can never happen adversarial
- 13The plain English reading of an expression explain
- 11Why a moment did not fire, the paste ready snippets, and clashes between schedules tools
- 10Every number printed on this page, checked against the code behind it figures
- 5A year pinned schedule, a rare one, and the cost of asking for more runs scale
- 9The fast answer against the minute by minute answer, in nine zones and across both clock changes oracle
- 8Every icon and image is the real brand asset, at the size the page claims brand
What it will not do
- It will not run anythingThis page reads and explains schedules. It is not a scheduler and has nothing to monitor.
- It will not tell you what your scheduler didIt tells you what the expression means. Whether your scheduler was awake, had the right timezone set, or was disabled for inactivity is a different question, and the page says which of those are known traps rather than pretending to know your logs.
- It will not repair a broken expressionIt names the field and the token that will not parse. Guessing at a repair would be guessing at your schedule.
- It will not cover every scheduler aliveSix dialects are read and written. Jenkins hashed syntax, systemd timers and Oracle DBMS_SCHEDULER are not among them.
- It will not predict a leap secondNor will your scheduler.
Questions people ask first
What happens to my job when the clocks go forward?
The hour it was set for does not exist that day, so it does not run. A job set for 02:30 in New York has no 02:30 on the March morning the clocks jump from 02:00 straight to 03:00. Nothing errors and nothing is logged, which is why this is usually noticed a day late, by someone looking for a report that never arrived. This page lists those runs under the table rather than leaving a silent gap in it.
And when the clocks go back?
That wall clock hour comes round twice, so the job can run twice. Unix cron, Kubernetes and EventBridge Scheduler document running it on the first occurrence only. A scheduler that wakes up and compares the clock to the expression can fire on both. This page marks every run that lands in the repeated hour so you can decide whether running twice would cost you anything.
Why does my schedule run on days I never asked for?
Almost always the day rule. If both the day-of-month and the day-of-week fields are restricted, POSIX cron fires when either one matches, not when both do. So 0 0 1 * 1 runs on the first of the month and on every Monday. The rule only applies when both fields are restricted; if one is a star, the other decides alone. The page flags this on any expression where it applies.
Which timezones can I pick?
Every one your browser knows, which is the full IANA set, normally a little over four hundred. There is no short list of capital cities here, because the zone you need is usually not on a short list. The names, the offsets and the daylight saving rules all come from the timezone database your browser already ships with, so they are as current as your browser is.
Can I convert an expression between schedulers?
Yes, and every conversion carries its own warnings. Going to a dialect without seconds drops the seconds field and says so. Going to a dialect without a year turns a one off into something annual and says so. Weekday numbers are renumbered when Sunday changes from 0 to 1. And where a conversion cannot be done honestly, such as restricting both day fields in Quartz, the page says that rather than producing something that looks correct.
Why will GitHub Actions not run my workflow every minute?
Because the shortest interval it schedules is five minutes. An expression faster than that is valid cron, commits cleanly, passes every linter, and then simply does not fire that often. The page warns whenever an expression converted to GitHub Actions asks for anything faster. The other common causes of a GitHub schedule not running are a public repository being disabled after sixty days without activity, and delays under heavy load.
Does anything get uploaded?
No. The parsing, the timezone maths and the run times are all worked out by code already in this browser tab, using the timezone database the browser ships with. There is no upload endpoint and no server waiting to receive anything. Disconnect after the page has loaded and it carries on working, which is checked by a test on every run.
Why does the page ask which dialect I am using?
Because the same five numbers mean different things to different schedulers. Sunday is 0 in Unix and 1 in Quartz. Seconds come first in Quartz and Spring and do not exist in the others. A question mark is required in two dialects, accepted in one, and rejected in three. Without knowing which one is reading your expression, any answer about when it runs is a guess.
Tell us where this is wrong
A schedule that this page reads differently from your scheduler is the most useful thing anyone can send us. The expression, the zone and the dialect are enough. toolssupport@apexautomationteam.com
- A run time this page gets wrong, with the zone you used
- A dialect you need that is not here yet
- A platform trap you have been bitten by that we have not written down
- A version of this wired into your own platform or workflow
- Something else altogether, built to your spec
Email our team See what we build
A wrong run time jumps the queue. Everything else is a feature request and waits its turn.