github mariusbancila/croncpp v2026.08.12
croncpp v2026.08.12

5 hours ago

New features:

  • L, W and # special characters - last day of month, last weekday, nearest weekday, last and Nth weekday of the month, across all traits (#18, #14)
  • Optional years field — the seventh field, 1970-2099, with *, ,, - and /; traits opt in via CRON_MIN_YEARS/CRON_MAX_YEARS (#22, #6)
  • cron_prev() - the last occurrence before a given time, for all three argument types (#5)
  • Day-of-month/day-of-week rule is now a traits property — POSIX traits match either field, Quartz and Oracle require ? in one (#12)
  • std::chrono overloads keep the caller's duration and report "no occurrence" as time_point::min() instead of an instant before the epoch (#10)

Fixes:

  • Daylight saving time - cron_next no longer returns a time in the past or skips an occurrence around a transition, and never returns a time at or before the one asked about (#34, #32, #24, #8)
  • Day of week was off by one under Quartz and Oracle traits - SUN fired on Monday, and a Sunday threw std::out_of_range (#35)
  • Fields that are not plain numbers are rejected instead of silently truncated - 15W was read as day 15, 256 as hour 0 (#36)
  • Dates that never occur are rejected at parse time, such as the 31st of February (#7)
  • Month names must stand alone - JAN1 was read as 11, meaning November
  • Expressions matching no time are refused rather than recursing until the stack overflows (PR #37)
  • Moving to a shorter month no longer skips it - a last-day-of-February expression jumped a leap year (same family as #30)

Behavior changes to note in the release:

  • Expressions restricting both day fields now mean "either" under the standard traits and are rejected under Quartz and Oracle; previously they required both to match
  • Expressions previously accepted and silently misread - 15W, 6#3, JAN1, 0 0 256 * * * - are now errors
  • L, W, # and a seventh field are now parsed rather than rejected
  • The std::chrono overloads return time_point::min() on failure, where they previously returned 1969-12-31 23:59:59

Don't miss a new croncpp release

NewReleases is sending notifications on new releases.