cronuru
Guide

Cron Dialect Comparison

Every cron-flavored scheduler started with Unix crontab and went its own direction. This guide is a side-by-side reference for the six dialects you're most likely to encounter — field counts, special characters, day-of-week numbering, default timezones, and the syntax differences that bite when you copy an expression from one system to another.

Updated

Quick overview

DialectFieldsSecondsYearDoW rangeSpecial charsDefault TZ
Unix50–6 (Sun=0)system local
Kubernetes50–6 (Sun=0)@hourly etc.UTC
GitHub Actions50–6 (Sun=0)UTC
Quartz6 or 7✓ (optional)1–7 (Sun=1)? L W #JVM default
AWS EventBridge61–7 (Sun=1)? L W #UTC
Spring @Scheduled60–7 (Sun=0 or 7)? L W #JVM default

Field counts and what they mean

5-field cron (Unix, Kubernetes, GitHub Actions) — minute, hour, day-of-month, month, day-of-week. Minimum granularity is 1 minute.

6-field cron with seconds (Quartz, Spring) — second, minute, hour, day-of-month, month, day-of-week. Minimum granularity is 1 second.

6-field cron with year, no seconds (AWS EventBridge) — minute, hour, day-of-month, month, day-of-week, year. Minimum granularity is 1 minute.

7-field cron (Quartz with optional year) — second, minute, hour, day-of-month, month, day-of-week, year.

If you paste a 5-field expression into a Quartz scheduler, you’ll get a parse error — the seconds field is missing. If you paste a 6-field Quartz expression into Unix crontab, the first field will be interpreted as minute, not second, and the schedule will be wrong by orders of magnitude.

Day-of-week numbering

The single most common porting bug:

  • Unix / Kubernetes / GitHub Actions: Sunday = 0, Saturday = 6
  • Quartz / AWS EventBridge: Sunday = 1, Saturday = 7
  • Spring @Scheduled: accepts both 0 and 7 as Sunday

“Weekdays only” in Unix is 1-5 (Mon–Fri). In Quartz it’s 2-6. The MON-FRI name form works in all dialects and avoids the off-by-one ambiguity entirely — prefer it.

Special characters

Every dialect supports *, ,, -, /. Beyond that:

CharMeaningWhere it works
?No specific value (placeholder for the unused field of day-of-month / day-of-week)Quartz, EventBridge (mandatory); Spring (optional)
LLast day of month (in DoM field); last day of week or “last X-day” (in DoW field)Quartz, EventBridge, Spring
WNearest weekday to a given day (e.g., 15W)Quartz, EventBridge, Spring
#The nth occurrence of a weekday in a month (e.g., MON#1 = first Monday)Quartz, EventBridge, Spring
@hourly, @daily, @weekly, @monthly, @yearlyNamed shortcutsLinux crontab, Kubernetes (some), Spring (5.3+)
@rebootOnce at system startupLinux crontab only

Quartz and EventBridge use ? as a mandatory placeholder — you cannot set both DoM and DoW to specific values. Pick one and put ? in the other.

Default timezones

This catches everyone at least once:

  • Linux crontab uses the system’s local timezone. Override per-crontab with CRON_TZ=UTC at the top of the file.
  • Kubernetes CronJob defaults to UTC. Set spec.timeZone for other zones (requires K8s 1.27+).
  • AWS EventBridge is UTC. No per-rule timezone.
  • GitHub Actions is UTC. No per-workflow timezone.
  • Spring @Scheduled uses the JVM’s default timezone. Set the zone annotation parameter (e.g., zone = "America/New_York") for a specific zone.
  • Quartz uses the JVM default. Set the trigger’s setTimeZone() explicitly.

If your job needs to run at a specific local time across DST transitions, pin the timezone explicitly. Don’t rely on the system default.

Same schedule, six dialects

“Every 5 minutes”:

Unix             */5 * * * *
Kubernetes       */5 * * * *
GitHub Actions   */5 * * * *
Quartz           0 */5 * * * ?
AWS EventBridge  */5 * * * ? *
Spring           0 */5 * * * *

“Every weekday at 9 AM”:

Unix             0 9 * * 1-5      (or 0 9 * * MON-FRI)
Kubernetes       0 9 * * 1-5
GitHub Actions   0 9 * * 1-5
Quartz           0 0 9 ? * MON-FRI
AWS EventBridge  0 9 ? * MON-FRI *
Spring           0 0 9 * * MON-FRI

“Last day of every month at midnight”:

Unix             — (cannot express directly; use script logic or 0 0 28-31 * * with a check)
Quartz           0 0 0 L * ?
EventBridge      0 0 L * ? *
Spring           0 0 0 L * *

Porting expressions between dialects

A quick checklist when copying an expression from one system to another:

  1. Field count — add or drop the seconds field. Add or drop the year field.
  2. DoW numbering01 and 67, or convert to name form (MON, TUE, etc.).
  3. Day-of-month vs day-of-week — if the target dialect requires ?, replace one of them. If the source uses ?, the target may need *.
  4. Special charsL, W, # won’t survive a port to Unix or Kubernetes. Either rewrite using * or skip those dialects entirely.
  5. Timezone — even if the syntax ports, the runtime timezone may not. Pin explicitly in the target system.

The parser tool handles all of this — paste any expression, switch dialects with the dropdown, and you’ll see whether it remains valid (and what changes).

Frequently asked questions

Why are there so many cron dialects?
Unix crontab came first and stayed minimal — 5 fields, no seconds, no year. Java's Quartz scheduler added seconds, year, and four extra special characters. AWS EventBridge took Quartz's `?` placeholder but kept the year field. Spring and Kubernetes each chose what they wanted from each. None of the variations are gratuitous — they fit the use cases of the systems that adopted them — but the result is a tangle of slight incompatibilities.
Which cron dialect should I learn first?
Standard Unix 5-field cron. It's the dialect crontab uses on every Linux system, the one Kubernetes CronJob accepts, the one GitHub Actions and Vercel and Cloudflare Workers all use. Quartz and its derivatives are easier to pick up once you understand the Unix baseline.
Can I write one cron expression that works everywhere?
For simple schedules, yes. `0 12 * * *` (noon daily) works in Unix, Kubernetes, GitHub Actions, and Vercel cron unchanged. Anything that uses `?`, `L`, `W`, `#`, seconds, or year fields will only work in Quartz / EventBridge / Spring. When in doubt, write the Unix form and convert per-platform.