Skip to content

Analizador de Expresiones Cron

Lee cualquier expresion cron en espanol claro, con las 10 proximas ejecuciones.

Compartir
*/15
Minute
0-59
9-17
Hour
0-23
*
Day of month
1-31
*
Month
1-12
1-5
Day of week
0-6 (Sun-Sat)
This schedule runs

Every 15 minutes from 09:00 to 17:45, Monday through Friday

Next 10 runs

Times in UTC
  1. Mon2026-09-1409:00
  2. Mon2026-09-1409:15
  3. Mon2026-09-1409:30
  4. Mon2026-09-1409:45
  5. Mon2026-09-1410:00
  6. Mon2026-09-1410:15
  7. Mon2026-09-1410:30
  8. Mon2026-09-1410:45
  9. Mon2026-09-1411:00
  10. Mon2026-09-1411:15

Common schedules

Free, no signup, 100% browser-side

Explain any cron expression, then prove it with the next 10 runs

Paste a 5-field crontab line. Get a plain-English description, a field-by-field breakdown, and the next 10 fire times in UTC. The run list is the point: it catches the schedules that read correctly and behave nothing like you intended.

How it works

Step 1

Paste the crontab line

Five fields, exactly as they appear in your crontab, Kubernetes CronJob, or CI schedule. Or click one of the common schedules to start from a known-good expression.

Step 2

Read it in English

The expression is described as a sentence, not a field-by-field dump. Every field is also broken out under the input with its label and legal range so you can see which value landed where.

Step 3

Check the next 10 fire times

Dated, weekday-labelled, in UTC. This is the part that catches mistakes a description can hide, because a wrong schedule almost always looks right in prose and obviously wrong in a list of dates.

Every feature, free

Next 10 runs, actually computed

Not an estimate. The scheduler walks forward day by day applying the real POSIX matching rules, including the day-of-month / day-of-week OR rule, and returns the first 10 timestamps strictly after the current minute.

Errors that say what is wrong

Not "invalid expression". You get the field and the reason: 60 is out of range for the minute field, 5-1 is not a valid range because a range must run low to high, L is not understood in the day-of-month field, this line has 4 fields and needs 5.

Field-by-field breakdown

The five boxes under the input show what you typed in each position next to its label and legal range. Off-by-one field ordering, the classic cause of a job running at 09 minutes past midnight instead of 09:00, is visible at a glance.

Readable step collapsing

"*/15 9-17 * * 1-5" reads as "Every 15 minutes from 09:00 to 17:45, Monday through Friday", using the real last fire time rather than the hour bound. Spelled out field by field it would be an unreadable list of 4 minutes crossed with 9 hours.

Names as well as numbers

jan through dec in the month field and sun through sat in the day-of-week field, case-insensitive. Both 0 and 7 are accepted for Sunday and normalised to the same day, which is where hand-written expressions often disagree with each other.

Never-fires detection

"0 0 31 2 *" is valid syntax that will never run, because 31 February does not exist. The tool searches 8 years ahead and tells you it found nothing, instead of showing a blank list or spinning.

Eight common schedules built in

Every minute, every 5 minutes, hourly, daily at midnight, weekdays at 09:00, weekly on Sunday, monthly on the 1st, and office hours every 15 minutes. Click one to load it, then edit from there.

Runs entirely in your browser

No request is made when you type. Crontab lines leak infrastructure detail (script paths, hostnames, backup targets, database names), and this one never leaves the tab.

The day-of-month / day-of-week trap

When both day fields are set, cron uses OR, not AND

Every other field in a cron expression is joined with AND. Minute AND hour AND month all have to match. The two day fields break that pattern. If day of month and day of week are both narrowed to something other than *, POSIX says the job runs when either one matches. This is specified behaviour, it is what your cron daemon actually does, and it is almost never what the person writing the line intended.

ExpressionReads asWhat actually happens
0 0 1 * *At 00:00 on day 1 of the monthOnce a month. Day of week is a wildcard, so only day of month is checked.
0 0 * * 1At 00:00, MondayOnce a week. Day of month is a wildcard, so only day of week is checked.
0 0 1 * 1At 00:00 on day 1 of the month, MondayAbout 5 times a month. Both day fields are restricted, so EITHER match is enough: every 1st plus every Monday.

Why nothing warns you

It is not a syntax error, so crontabaccepts the line without complaint. It is not a runtime error either, because the job runs fine, just more often than planned. And the English description sounds reasonable: "at 00:00 on day 1 of the month, Monday" is a sentence most people read as a single constrained event rather than two independent triggers. The failure surfaces weeks later as duplicate invoices, a report emailed 5 times a month, or a backup window that keeps colliding with something else.

How to catch it in 3 seconds

Look at the two day fields. If neither is *, the OR rule is live and the run list is the only trustworthy answer. Scan the next 10 dates: unexpected weekdays mixed into a monthly schedule, or unexpected dates mixed into a weekly one, confirm it immediately. That is exactly the check a description alone cannot give you, and the reason this tool always shows real timestamps.

There is no AND, so use the job itself

"The 1st of the month, but only when it falls on a Monday" cannot be written in POSIX cron. The intersection does not exist in the syntax. The standard fix is to schedule on one field and guard on the other inside the script:

# fires every 1st; the guard drops the non-Monday ones
0 0 1 * *  [ "$(date -u +\%u)" = "1" ] && /opt/jobs/monthly-close.sh

Percent signs are escaped because crontab treats a bare % as a newline in the command. That is a second, unrelated trap in the same line, and it is worth knowing before you paste a date format into a crontab.

Cron syntax reference

FieldAllowed valuesOperatorsExample
Minute0-59* , - /*/15 means 00, 15, 30, 45
Hour0-23* , - /9-17 means 09:00 through 17:00
Day of month1-31* , - /1,15 means the 1st and the 15th
Month1-12 or jan-dec* , - /*/3 means January, April, July, October
Day of week0-6 or sun-sat (7 = Sunday)* , - /1-5 means Monday through Friday
*

Every value the field allows.

5

Exactly that value.

1,15,30

A list. Each term is expanded and the results merged.

9-17

An inclusive range. It must run low to high, so 17-9 is an error rather than a wrap-around.

*/15

Every 15th value starting from the bottom of the field.

0-30/10

A step inside a range: 0, 10, 20, 30.

5/15

A step from a start value to the top of the field: 5, 20, 35, 50 in the minute field.

What people use it for

Review a crontab you inherited

Paste each line and read what it does before you touch it. The next-10 list tells you whether that nightly job you assumed runs at 02:00 actually runs at 02:00, or at 2 minutes past every hour.

Verify a Kubernetes CronJob schedule

A CronJob spec takes the same 5-field syntax. Check the schedule before you apply the manifest, because a wrong schedule in a cluster is a job that quietly runs 60 times an hour.

Debug a job that fires too often

The most common cause is the day-of-month / day-of-week OR rule. If your monthly job is running weekly, look at the two day fields: if both are set, that is your answer.

Write a schedule from a requirement

Start from a preset that is close, edit it, and watch the run list update as you type. It is faster than reasoning about field semantics and far harder to get wrong.

Sanity-check a CI or backup window

Confirm that the backup window and the deploy window do not overlap by parsing both expressions and comparing their next runs, all in UTC so the comparison is apples to apples.

Explain a schedule in a PR or runbook

Copy the plain-English line into the pull request description or the runbook so the next reader does not have to parse the cron syntax in their head.

Walkthroughs

Check whether a schedule really is monthly

  1. 1Paste the expression, for example "0 0 1 * 1".
  2. 2Read the description. It will mention both a day of the month and a weekday.
  3. 3Look at the next 10 runs. If Mondays appear between the 1sts, the OR rule is firing.
  4. 4Fix it by setting the day-of-week field back to *, giving "0 0 1 * *".

Build an office-hours schedule

  1. 1Click the "Office hours, every 15 min" preset to load "*/15 9-17 * * 1-5".
  2. 2The description reads "Every 15 minutes from 09:00 to 17:45, Monday through Friday". Note 17:45, not 17:00: the 17 hour still gets all four of its minute slots.
  3. 3Change 9-17 to your own window and the run list updates immediately.
  4. 4If you want the last run at 17:00 exactly, use "*/15 9-16 * * 1-5" plus a separate "0 17 * * 1-5" line.

Convert a macro to real cron

  1. 1Macros like @daily and @hourly are not parsed here, and plenty of schedulers do not accept them either.
  2. 2@hourly is "0 * * * *", @daily is "0 0 * * *", @weekly is "0 0 * * 0".
  3. 3@monthly is "0 0 1 * *", @yearly is "0 0 1 1 *".
  4. 4Paste the expanded form to confirm it matches what the macro promised.

Find out if an expression ever fires

  1. 1Paste it, for example "0 0 31 2 *".
  2. 2The syntax is legal, so there is no error banner.
  3. 3The run list is empty and says the expression never fires within 8 years.
  4. 4The usual cause is a day-of-month that cannot occur in the selected month. "0 0 29 2 *" is the milder version: it is real, but only on leap days, so it returns 2 entries instead of 10.

Traps, and what this parser will not do

Cron has no timezone

An expression is just five numbers. Whatever daemon runs it decides what "09:00" means. Cloud hosts usually run UTC, a laptop usually does not, and a container inherits whatever its image was built with. This tool answers in UTC and labels it, so you compare against your server's clock deliberately rather than by accident.

Daylight saving is the daemon's problem

On a machine running local time, a daily job scheduled inside the DST transition window can run twice or not at all on those two days a year. Nothing in the expression can prevent it. Scheduling in UTC does.

No seconds field

Quartz, Spring, and several Node schedulers use a 6-field form where the first field is seconds. Paste one here and you get an error about field count, which is the correct answer: the same string means different things in the two dialects, and guessing which one you meant would be worse than refusing.

No L, W, #, or ?

Those are Quartz extensions, not POSIX cron. "Last day of the month" and "third Friday" cannot be written in standard cron at all. The usual workaround is to schedule wider and exit early from the script when the date is wrong.

Field order is the quiet killer

Minute comes first, hour second. "9 0 * * *" is 00:09 daily, not 09:00. The field breakdown under the input exists specifically to make that visible before you commit the line.

Steps count as restricted

A step like */2 in the day-of-month field is not a wildcard. It narrows the field, which means it is enough to trigger the day-of-month / day-of-week OR rule if the weekday field is also set.

Privacy + security

Your expression never leaves the tab

Parsing, describing, and scheduling are pure functions running in your browser. No request is made when you type, nothing is logged, and the tool keeps working with the network disconnected after the first page load.

That is not a small thing for this particular tool. A real crontab line usually carries a script path, sometimes a hostname, a database name, an S3 bucket, or a credential-shaped argument. Pasting one into a hosted parser hands a stranger a partial map of your infrastructure. Here there is no server to hand it to.

Who it's built for

Sysadmins and SREs

Auditing an inherited crontab, moving jobs between hosts, or checking a schedule before it goes into a change window. The run list is the review artifact.

Backend and platform engineers

Kubernetes CronJobs, systemd timers written from a cron spec, queue workers, scheduled Lambdas. Same 5-field syntax, same OR rule, same off-by-one field mistakes.

Data engineers

Pipeline schedules where a job firing twice is worse than a job not firing at all. Verify the interval and confirm two schedules do not overlap before either is deployed.

Anyone reviewing someone else's cron

You do not need to know cron semantics to review a schedule if you can read 10 dates. That is the whole idea behind putting the run list next to the description.

Questions people ask

What does this cron expression parser do?
You paste a standard 5-field crontab line and it gives you two things back instantly: a plain-English sentence describing the schedule, and the next 10 times the job will actually fire. So "*/15 9-17 * * 1-5" comes back as "Every 15 minutes from 09:00 to 17:45, Monday through Friday" followed by a dated list you can check against what you expected.
Why does 0 0 1 * 1 fire far more often than once a month?
Because of the POSIX day-of-month / day-of-week OR rule. When both day fields are set to something other than *, cron runs the job when EITHER field matches, not when both match. So "0 0 1 * 1" fires at midnight on the 1st of every month AND at midnight every Monday, roughly 5 times a month instead of once. It is not a syntax error, nothing warns you, and the description line reads innocently. The next-10-runs list is where you catch it: you will see Mondays in there.
How do I write "the 1st of the month, but only if it is a Monday"?
You cannot, not in a single POSIX cron expression. The two day fields are joined with OR, never AND, so there is no way to express an intersection. The standard workaround is to schedule on one field and check the other inside the job: run "0 0 1 * *" and have the script exit early unless the weekday is Monday, or run "0 0 * * 1" and exit early unless the date is the 1st.
Which timezone are the run times in?
UTC, always, and the tool says so next to the list. A cron expression carries no timezone of its own, so the honest answer cannot depend on who is reading the page. Your actual server interprets the same expression in whatever timezone its cron daemon uses (often UTC on cloud hosts, often local time on a workstation), so compare the UTC list against your server's clock, not your own.
Does it support @daily, @reboot, or 6-field cron with seconds?
No. The parser handles the standard 5-field POSIX form only: minute, hour, day of month, month, day of week. Macros like @daily and @reboot, the seconds field used by Quartz, Spring, and some Node schedulers, and Quartz extensions such as L, W, #, and ? are all rejected with an error rather than silently guessed at. Convert to the 5-field form first: @daily is "0 0 * * *", @hourly is "0 * * * *", @weekly is "0 0 * * 0", @monthly is "0 0 1 * *", @yearly is "0 0 1 1 *".
What syntax is supported inside a field?
Wildcards (*), single values (5), lists (1,15,30), ranges (9-17), steps on a wildcard (*/15), steps on a range (0-30/10), and steps from a start value (5/15, meaning from 5 to the end of the field in increments of 15). Month accepts jan through dec and day of week accepts sun through sat, case-insensitive. Both 0 and 7 mean Sunday in the day-of-week field.
Why does my expression show fewer than 10 runs, or none at all?
The scheduler searches 8 years ahead and returns whatever it finds. "0 0 29 2 *" only lands on leap days, so it shows 2 entries, not 10. "0 0 31 2 *" shows none at all: 31 February never happens, so the expression is valid syntax that will never once fire. An empty or short list is real information, not a bug in the tool.
Is my expression sent to a server?
No. The parser, the describer, and the scheduler are pure JavaScript running in your tab, with no network call at any point. That matters more than it sounds: crontab lines routinely contain internal hostnames, script paths, database names, and backup targets, and pasting one into a hosted tool hands over a small map of your infrastructure. Nothing here leaves the page.
Why is */2 in the day-of-month field enough to trigger the OR rule?
Because "restricted" means anything other than a bare wildcard, not just a fixed number. "*/2" narrows the day-of-month field to odd days, so it counts as restricted, and if the day-of-week field is also set you get the OR behaviour. "0 0 */2 * 1" fires on every odd day of the month plus every Monday. The description spells the day list out in full so you can see exactly what got expanded.
Is it free?
Yes. No signup, no daily cap, no rate limit, no ads in the results. The whole tool is a few kilobytes of JavaScript with no backend, so there is nothing for us to meter.

Try it now

Paste a cron line, see the next 10 runs

Free. No signup. Nothing sent anywhere. The fastest way to find out whether that schedule does what you think it does.

Parse an expression
Creado y revisado porMolixa AI, Molixa AI
Última actualización:

La página de Analizador de Expresiones Cron es creada, revisada y mantenida por el equipo de Molixa. Usamos la herramienta que publicamos y actualizamos la documentación cuando el comportamiento cambia.