Cron tools › Build / Generate
Cron to code
Enter a Linux cron expression and a time zone and copy a working snippet for your scheduler library. Where a library reads the day fields differently from Linux cron, the snippet is rewritten so it still means the same schedule — and where cronkit can simulate the library, it proves it run by run.
How to turn a cron expression into code
- Type or paste a five-field Linux cron expression; macros such as
@dailywork too. For a Quartz or Spring expression, convert it first with Quartz to cron. - Pick the time zone the job should follow. Every snippet sets it explicitly, so the job does not silently run in the server's zone.
- Jump to your library and read the note under its snippet: a green check means cronkit parsed the output with that library's rules and got the same runs as your input.
- Copy the snippet and replace the placeholder job body.
How the libraries read the day fields
The same five fields do not mean the same thing everywhere. When both day of month and day of week are set, Linux cron runs when either matches; several libraries require both. The snippets split such a schedule into two, one per day field, which means the same thing under either rule.
| Target | Both day fields set | Weekday numbers | What the snippet does |
|---|---|---|---|
| node-cron | AND | 0-7, 0 and 7 = Sunday | Splits an OR into two cron.schedule calls; checked |
Celery crontab() | AND | 0-6, Sunday = 0; names | Two beat entries for an OR; keyword arguments; checked |
Spring @Scheduled | AND | 0-7 or MON-SUN | Six fields, two methods for an OR; checked |
| Quartz | one must be ? | 1-7, 1 = Sunday | Names, two triggers for an OR; checked |
| robfig/cron (Go), Kubernetes | OR unless one is a bare * | 0-6 | Same string when the rules agree; refused when Linux would AND; checked |
| GitHub Actions | not documented | 0-6 | Two cron entries for an OR |
| APScheduler, Laravel, cron-expression, Hangfire, sidekiq-cron | not verified here | — | Only schedules with at most one day field set, which read the same under any rule |
A Linux schedule that ANDs the day fields — 0 0 */2 * 1, "Mondays on odd dates", because a field starting with * switches Linux cron to AND —
has no safe equivalent in the OR libraries or the ones whose rule is not verified here, so for those the page explains the workaround instead of printing a snippet that means something else.
Where the time zone goes
| Target | Setting |
|---|---|
| node-cron | { timezone: 'Europe/Berlin' } |
| APScheduler | CronTrigger(…, timezone="Europe/Berlin") |
| Celery | app.conf.timezone = "Europe/Berlin" |
| Spring | @Scheduled(cron = "…", zone = "Europe/Berlin") |
| Quartz | .inTimeZone(TimeZone.getTimeZone("Europe/Berlin")) |
| Laravel | ->timezone('Europe/Berlin') |
| robfig/cron | cron.New(cron.WithLocation(loc)) |
| Hangfire | new RecurringJobOptions { TimeZone = … } |
| sidekiq-cron | cron: "0 9 * * 1-5 Europe/Berlin" |
| Kubernetes | spec.timeZone: "Europe/Berlin" |
| GitHub Actions | timezone: "Europe/Berlin" |
More options per platform: the Kubernetes CronJob generator (concurrency policy, deadlines, history limits), GitHub Actions schedule (the 5-minute floor and UTC), Spring cron and Celery crontab().
FAQ
Why does APScheduler get day names instead of numbers?
APScheduler numbers weekdays differently from Linux cron, so a 1-5 copied across does not mean Monday to Friday there. Names such as mon-fri
are unambiguous, so the snippet always uses them.
What does the green check mean?
cronkit re-parsed the snippet's expression with that scheduler's rules — field layout, weekday numbering, how the day fields combine — and compared the next 300 run times with your input. The check is about which clock times match; what a library does in the hour daylight saving time skips or repeats is its own behaviour, so look at the runs around the change dates in the next run calculator. Targets without a check are written from standard five-field syntax that every cron parser reads the same way, but are not simulated.
Why is there no Rust snippet?
cronkit only prints code for library APIs it has checked, and no Rust scheduler crate is covered yet. Check your crate's documentation for its field layout — some expect a seconds field in front — before pasting a five-field expression in.
Why must Celery use keyword arguments?
Positionally, crontab() takes minute, hour, day_of_week, day_of_month, month_of_year — day of week third, unlike a cron line where it is last.
Keywords make the mapping impossible to get wrong.