HandyTools Hub

Cron Expression Generator

Generate and understand cron expressions with visual builder.

Direct Input

Visual Builder

Common Presets

Result

Valid cron expression

Next 5 Executions

    Cron expressions are famously terse: five space-separated fields that decide exactly when your backups run, your emails send, and your reports generate. They are also famously easy to get wrong. This visual builder lets you pick values with dropdowns or start from a preset, shows the resulting expression, describes it in plain English, and previews the next five execution times in your chosen timezone — so you can be confident before pasting anything into a crontab.

    How the Five Fields Fit Together

    The fields always appear in the same order:

    PositionFieldAllowed values
    1Minute0–59
    2Hour0–23
    3Day of month1–31
    4Month1–12
    5Day of week0–7 (0 and 7 are Sunday)

    Four operators modify a field. An asterisk * matches every value. A comma lists alternatives, so 0 9,17 * * * runs at 9 AM and 5 PM. A hyphen gives a range, so 0 9 * * 1-5 runs at 9 AM Monday through Friday. A slash gives a step, so */10 * * * * runs every 10 minutes. The builder offers these as menu entries, and typing a value the menu does not list adds it as a custom option rather than rejecting it.

    Operators combine, which is where most of cron’s expressive power lives. 0 9-17 * * 1-5 means every hour on the hour from 9 AM to 5 PM on weekdays — 9:00, 10:00, and so on through 17:00. */30 9-17 * * 1-5 narrows that to twice an hour during the working day. 0 0 1,15 * * runs on the 1st and 15th. 0 0 * * 0,6 runs at midnight on both weekend days. Read a field left to right as a set of allowed values, and remember that each field is evaluated independently against the current time; there is no cross-field arithmetic, so “every 90 minutes” is not expressible as a single cron line.

    Reading an Expression in Plain English

    The result panel explains the current expression, which is the fastest way to catch a misunderstanding. 0 0 * * * reads as “at 12:00 AM, every day”; 0 9 * * 1-5 as “at 9:00 AM, Monday through Friday”; 0 0 1 1 * as “at 12:00 AM, on day 1 of the month, only in January.” If the English does not match what you intended, the fields are wrong — no guessing required.

    Worked Examples

    ExpressionMeaning
    * * * * *Every minute
    */5 * * * *Every 5 minutes (0, 5, 10, …)
    0 * * * *Every hour, on the hour
    0 0 * * *Daily at midnight
    0 9 * * 1-5Weekdays at 9 AM
    0 0 * * 0Every Sunday at midnight
    0 0 1 * *First day of every month
    0 0 1 1 *Once a year, on January 1

    Note that 0 0 1 * * means the first of the month, while 0 0 * * 1 means every Monday — position matters, and the two look similar at a glance.

    A useful habit is to read the expression one field at a time and say “minute, hour, day, month, weekday” out loud. 15 14 1 * * is “minute 15, hour 14, day 1, any month, any weekday” — 2:15 PM on the first of each month. If that mental sentence does not match your intent, change the field before you copy the string. The explanation panel does this translation for you, so the fastest sanity check is simply to see whether the plain-English sentence describes the job you meant to schedule.

    The Day-of-Month / Day-of-Week Trap

    When both the day-of-month and day-of-week fields are restricted, cron uses OR logic. 0 0 13 * 5 does not mean “Friday the 13th.” It means “the 13th, and also every Friday.” To run only on a specific weekday that falls on a specific date you need application-level logic or a scheduler with richer syntax. This rule trips up experienced users because it contradicts the AND logic they assume applies everywhere else.

    Timezones and Next-Run Previews

    Cron itself stores no timezone; it evaluates against the host’s clock. The preview here converts the next five runs into a timezone you select, defaulting to your browser’s zone, which makes DST shifts and UTC servers visible before deployment. The two failure modes worth checking are a server running UTC while you meant local time, and a job scheduled in the 2 AM hour on a DST transition day, when that wall-clock time may not exist.

    The relative labels next to each previewed run (“in 3 hours,” “in 2 days”) are computed from the current moment, so they refresh as time passes and make it obvious when a schedule is far sparser than intended. If a job you expected hourly shows its next run “in 7 days,” a field is restricting something you did not mean to restrict. Because the preview uses your browser’s clock and the host runs on its own, always confirm the production timezone rather than assuming the two agree.

    Common Mistakes and Dialect Differences

    • Confusing minute and hour positions, turning an hourly job into a per-minute one.
    • Assuming */15 is relative to deployment time rather than the top of the hour.
    • Using 7 for Sunday in a system that only accepts 0–6, or vice versa.
    • Expecting L, W, and # to work everywhere — they are Quartz extensions, not portable cron, and this validator checks the standard five-field form.
    • Forgetting that managed platforms rename or reorder fields, so an expression copied from a crontab may need editing before it works in GitHub Actions or EventBridge.

    Frequently Asked Questions

    Why does my cron job run at the wrong hour?

    Almost always a timezone mismatch. Classic cron evaluates the schedule in the server's local timezone, which may be UTC even though you are thinking in your own time. This tool previews the next five runs in a selectable timezone so you can see the actual wall-clock times. On Linux you can also force the question by setting CRON_TZ=UTC (or another zone) at the top of the crontab, and managed schedulers such as GitHub Actions, Kubernetes CronJobs, and AWS EventBridge have their own timezone settings.

    What happens when both day-of-month and day-of-week are restricted?

    Cron ORs them, not ANDs them. If neither field is `*`, the job runs when either field matches. So `0 0 13 * 5` fires on the 13th of every month and on every Friday — not only on Friday the 13th. This is the single most common source of surprise executions.

    Does */15 * * * * run every 15 minutes from when I save it?

    No. Steps are anchored to the start of the field, not to when the job was created. `*/15` fires at minute 0, 15, 30, and 45 of every hour. If you need a different phase you have to write it out, for example `5 * * * *` to run at minute 5.

    This tool uses five fields, but I have seen six or seven. Why?

    Five fields (minute, hour, day of month, month, day of week) is the classic Unix crontab format. Quartz and some Java schedulers add a leading seconds field and a trailing year field, so they use six or seven. AWS EventBridge uses a six-field form with minutes first. Field order and special characters differ between dialects, so test in the target system.

    Will 0 0 31 2 * ever run?

    No. February never has a 31st, so that expression is syntactically valid but can never fire. Schedulers do not warn you about impossible combinations. If a monthly job needs the last day of the month, remember that portable five-field cron has no last-day token; use a wrapper script or a scheduler that supports `L`.

    What is the difference between 0 * * * * and * * * * *?

    `0 * * * *` runs once an hour, at minute zero. `* * * * *` runs every single minute — 1,440 times a day. Adding a specific value in the minute field is the difference between an hourly and a per-minute schedule, and it is easy to miss when skimming an expression.

    Reviewed by the HandyTools Hub team · Last updated