Calculate the next several run times for a given cron expression and timezone.
A cron expression's 5 fields (minute, hour, day-of-month, month, day-of-week) each define a set of matching values, and a candidate minute must satisfy all fields — except for the classic cron quirk where, if both day-of-month and day-of-week are restricted (not '*'), a match on either field alone is sufficient (an OR rather than AND between just those two fields). This calculator walks forward minute-by-minute from the current time, checking each candidate against the parsed field sets, until it finds the requested number of upcoming matches — the same effective logic the cron daemon itself uses to decide when to fire.
Day-of-month / day-of-week matching rule
A candidate day matches if: (DOM='*' AND DOW='*') OR (DOM='*' AND dow_matches) OR (dow='*' AND dom_matches) OR (dom_matches OR dow_matches) when both are restricted
This is a well-known cron quirk: when both day-of-month and day-of-week are restricted to specific values (not '*'), cron treats them as an OR, not an AND. So this expression fires at midnight on the 15th of every month, and separately at midnight every Monday — not only on Mondays that happen to be the 15th.
It calculates relative to the current server/browser time context in which this calculator runs. Real crontabs run in the timezone configured for the cron daemon (often UTC or system-local time, sometimes overridable per-job via a CRON_TZ variable in modern cron implementations) — always verify against the actual server's `date` and cron configuration for production scheduling decisions.
No — this calculator expects standard 5-field cron syntax (minute hour dom month dow). Special strings like @daily, @hourly or @reboot are shorthand supported by some cron implementations (like cron/vixie-cron) but would need to be translated to their 5-field equivalent first (e.g. @daily = '0 0 * * *') before using this calculator.