Migrating Cron Schedules to Databricks (Quartz) and EventBridge Without Surprises
Convert Unix cron to Quartz or EventBridge, with a warning for every rule that changes
No signup • Runs in browser • Free
A crontab line copied into Databricks or AWS EventBridge usually fails in one of two ways: it is rejected, or it is accepted and runs on the wrong day or at the wrong hour. The second is worse, because nothing reports it. The three formats look alike, but they disagree on the number of fields, how weekdays are numbered, how the two day fields combine, and which timezone the hours mean.
Unix crontab 0 9 * * 1-5 09:00 Mon–Fri, server timezone
Databricks/Quartz 0 0 9 ? * 2-6 09:00 Mon–Fri, job timezone
EventBridge cron(0 9 ? * 2-6 *) 09:00 Mon–Fri, UTC
Quick summary
- ✓Quartz adds a seconds field at the front; EventBridge adds a year field at the end.
- ✓Quartz and EventBridge number Sunday as 1, Unix as 0 — 1-5 means Sunday to Thursday after a straight copy.
- ✓Quartz and EventBridge need ? in one day field, so the Unix day-of-month OR day-of-week rule cannot be copied.
- ✓EventBridge scheduled rules run in UTC; Databricks jobs run in the job's timezone; crontab runs in the server's.
- ✓DevToolBox tools run entirely in your browser — no signup.
- Field layout
| Dialect | Fields | Example |
|---|---|---|
| Unix cron | minute hour day-of-month month day-of-week | 30 2 * * * |
| Quartz (Databricks) | second minute hour day-of-month month day-of-week [year] | 0 30 2 * * ? |
| EventBridge | cron(minute hour day-of-month month day-of-week year) | cron(30 2 * * ? *) |
Quartz has 6 required fields plus an optional year (1970–2099). EventBridge has 6 required fields with the year last (1970–2199), wrapped in cron(...), and no seconds. A Quartz expression that fires at a non-zero second, such as 30 0 9 * * ?, cannot move to Unix or EventBridge at all — neither has a seconds field. The Cron Converter refuses it rather than dropping the seconds silently.
- Weekday numbers
Unix cron numbers day-of-week 0–6 with Sunday = 0 (most implementations also accept 7 for Sunday). Quartz and EventBridge use 1–7 with Sunday = 1. Copying 1-5 keeps it valid, so nothing warns you, but the meaning moves from Monday–Friday to Sunday–Thursday.
Two ways to avoid this:
- Use names.
MON-FRImeans the same in all three dialects. - Add 1 to every number. Unix
7(Sunday) becomes1, and a range like5-7(Friday to Sunday) cannot stay a range because Sunday wraps to the start; the converter writes such days out as a list (1,6,7).
- The two day fields
In Unix cron (cronie and Vixie cron), when both day-of-month and day-of-week are restricted, the job runs on days matching either one. 0 9 1 * 1 runs at 09:00 on the 1st of the month and on every Monday. The exception: if either field starts with *, as in */2, both must match — 0 0 */2 * 1 runs only on odd-numbered days that are Mondays.
Quartz and EventBridge do not support restricting both. One of the two must be ? ("no specific value"). So:
0 9 * * 1(Unix) → day-of-month becomes?:0 0 9 ? * 2(Quartz),cron(0 9 ? * 2 *)(EventBridge).0 9 1 * *(Unix) → day-of-week becomes?:0 0 9 1 * ?,cron(0 9 1 * ? *).0 9 1 * 1(Unix) → no single equivalent. Create two schedules, one for the 1st and one for Mondays, and make sure the job tolerates running twice when the 1st is a Monday.
- L, W and #
Quartz and EventBridge can schedule the last day, last weekday, nearest weekday and nth weekday of a month directly, using L, W and #. Unix cron cannot, which is why crontabs often contain shell workarounds such as [ "$(date +%d -d tomorrow)" = "01" ] && run-job. Their replacements:
| Need | Quartz | EventBridge |
|---|---|---|
| Last day of the month | 0 0 18 L * ? | cron(0 18 L * ? *) |
| Last weekday of the month | 0 0 18 LW * ? | not listed in the AWS reference |
| Two days before month end | 0 0 18 L-2 * ? | not supported |
| Weekday nearest the 15th | 0 0 9 15W * ? | cron(0 9 15W * ? *) |
| Last Friday | 0 15 10 ? * 6L | cron(15 10 ? * 6L *) |
| Second Tuesday | 0 0 9 ? * 3#2 | cron(0 9 ? * 3#2 *) |
None of these exist in Unix cron, so going back the other way is blocked. EventBridge also allows only one # expression in day-of-week: 3#1,6#3 is invalid. Check any of these on the Quartz Cron Generator or the EventBridge validator, which list the next five runs.
- rate() expressions
EventBridge also accepts rate(value unit), such as rate(5 minutes). The unit is singular for 1 and plural above 1: rate(1 hour) and rate(2 hours) are valid, rate(1 hours) is not.
A rate starts counting when the schedule starts — rule creation, or the EventBridge Scheduler start date — while cron runs on clock boundaries, so the converter does not turn a rate into cron. It can suggest a clock-aligned alternative and says how it differs. rate(15 minutes) and */15 * * * * both run four times an hour, but not necessarily at :00, :15, :30 and :45. Intervals that do not divide the hour or day — rate(7 minutes), rate(3 days) — have no cron equivalent, because cron steps restart every hour, day or month.
- Timezones and DST
The same hours mean different things on each platform:
- Unix crontab: the server's timezone, unless the cron implementation supports
CRON_TZor the job setsTZ. - Databricks: the timezone set on the job schedule (the Jobs API stores it next to
quartz_cron_expressionastimezone_id). - EventBridge scheduled rules: UTC. EventBridge Scheduler, which AWS now recommends for schedules, lets you choose a timezone.
If the crontab ran in a local timezone with daylight saving time, a UTC schedule shifts by an hour against local time twice a year. If you keep a local timezone, look at the runs around the transition dates — in 2026, 8 March and 1 November for America/New_York, 29 March and 25 October for Europe/London. What happens to a run in the skipped or repeated hour depends on the scheduler:
- cronie (man page): a fixed-time job in the skipped hour runs right after the change, and a job in the repeated hour is not run twice. Jobs that run more often than hourly are scheduled normally.
- EventBridge Scheduler (AWS docs): a run in the skipped hour is skipped, and a run in the repeated hour happens once.
- EventBridge scheduled rules: UTC only, so nothing is skipped or repeated.
- Quartz: the CronTrigger tutorial does not say. Avoid the transition hour or use UTC.
The validators take a timezone and a reference date, list local and UTC run times, and mark runs that fall in a skipped or repeated hour. Set the reference date just before a transition to check it.
Migration checklist
- Export every schedule with the timezone it currently runs in.
- Convert each expression with the Cron Converter and read every warning.
- Split any Unix schedule that restricts both day fields into two schedules.
- Replace numeric weekdays with names (
MON-FRI) where the target allows it. - Set the timezone explicitly: the Databricks job timezone, or shift hours to UTC for EventBridge rules.
- Paste each result into the Quartz or EventBridge validator and compare the next five runs with the old schedule's runs from the Cron Builder.
- For local-timezone schedules, check the runs around the DST dates above.
Frequently Asked Questions
Can I paste a crontab line into Databricks if I just add a 0 in front?
Not safely. Adding a seconds field fixes the field count, but you still need ? in one day field, and any numeric weekday must shift by one (Unix Sunday = 0, Quartz Sunday = 1). 0 9 * * 1-5 becomes 0 0 9 ? * 2-6, not 0 0 9 * * 1-5.
Why does EventBridge reject an expression that works in Quartz?
Usually because of the seconds field: EventBridge has none, and ends with a required year instead. 0 0 12 ? * MON-FRI in Quartz is cron(0 12 ? * MON-FRI *) in EventBridge. L-n is also Quartz-only.
Do weekday names behave the same in every dialect?
Yes. SUN to SAT and JAN to DEC mean the same in Unix cron, Quartz and EventBridge, which is why names are the safest way to write schedules you might move later.
Convert a cron schedule in seconds
Unix, Quartz and EventBridge, with a warning for every rule that changes. Free, no signup, browser-only.
Open Cron Converter →