Timestamps and scheduling guides
Leap-day Cron: verify February 29 schedules
Preview rare calendar matches and apply Gregorian leap-year rules rather than assuming a four-year interval.
Express the calendar date
A five-field expression can select midnight on February 29. This is a calendar match, not a fixed-duration four-year timer.
Use UTC for the first fixture so timezone transitions do not obscure the leap-year question.
0 0 29 2 *
Start: 2025-01-01T00:00:00Z
Next: 2028-02-29T00:00:00ZApply the century exception
Gregorian leap years are divisible by four, except century years must also be divisible by 400. The year 2100 is not a leap year.
A once-per-four-years arithmetic shortcut will eventually diverge from the calendar rule.
2000: leap year
2100: not a leap year
2400: leap yearDistinguish no date from a parser error
A skipped nonleap year is expected behavior. A parser may also impose a search horizon that affects very distant previews.
Test a start close to the next valid date and inspect actual parser errors instead of declaring every empty preview an invalid expression.
Define the nonleap-year business rule
For birthdays or annual reporting, the product may need February 28 or March 1 in nonleap years. That is different from running only on February 29.
Implement that policy in application code and test both leap and nonleap years. Cron previews do not invent a replacement date.