New features:
L,Wand#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 viaCRON_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::chronooverloads keep the caller's duration and report "no occurrence" astime_point::min()instead of an instant before the epoch (#10)
Fixes:
- Daylight saving time -
cron_nextno 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 -
SUNfired on Monday, and a Sunday threwstd::out_of_range(#35) - Fields that are not plain numbers are rejected instead of silently truncated -
15Wwas 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 -
JAN1was 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::chronooverloads returntime_point::min()on failure, where they previously returned1969-12-31 23:59:59