Skip to content

v2.2.6

Choose a tag to compare

@ggaabe ggaabe released this 17 Sep 20:41
· 26 commits to main since this release

This patch fixes recurrence correctness issues reported in #139, #140, and #141, plus related defects found by the optimization audit and independent fuzzing.

  • Fixed invalid inherited dates in MONTHLY and YEARLY rules (#140). Missing
    days are omitted without consuming COUNT or changing later occurrences;
    January 31 stays on the 31st and February 29 stays on leap days. BYMONTH,
    interval alignment, numeric queries, and RSCALE SKIP use the same policy.
  • Fixed generated starts in DST gaps being shifted and counted (#141).
    Calendar dates remain nominal until time expansion, and nonexistent times
    are omitted before BYSETPOS and COUNT. Explicit DTSTART/RDATE inputs and
    the first occurrence of a repeated local time retain their interpretation.
  • Fixed weekly BYSETPOS ranking before date filters, backward-moving subdaily
    cursors after time overrides in gaps, RSCALE partial-period termination,
    and occursOn() boundaries on shortened or skipped calendar dates.
  • Stopped bounded monthly fast paths at UNTIL even when no candidates match.
    Added direct RFC regressions and an independent seeded calendar oracle,
    alongside the existing optimization/query differential fuzzing.
  • Fixed between() forcing an aligned query anchor into the recurrence set
    when includeDtstart is enabled (#139). All query methods now share the
    same rule for retaining inclusion of the real DTSTART.
  • Preserved DAILY INTERVAL cadence through weekday filters in both general
    generation and optimized generation/queries.
  • Preserved calendars in query anchors and optimized output, and clipped
    period bounds using the candidates' timezone and calendar.
  • Preserved inherited fields when seeking month ends and leap days without
    replaying the rule's entire history. RSCALE and unsupported calendar
    alignment shapes retain the general traversal.
  • Fixed DST wall-time drift in weekly/period generation, skipped time slots
    after gaps, and phantom HOURLY occurrences during fall-back. Calendar fold
    occurrences use the first instant while explicit later-fold DTSTART values
    retain their meaning and bypass incompatible fast paths.
  • Ordered mixed positive/negative week numbers before streaming and applying
    COUNT, included week-year spillover at query bounds, and respected WKST and
    non-ISO year lengths when counting weeks.
  • Fixed cached timezone transitions shifted by input milliseconds or missed
    by fifteen-day sampling. Native Temporal reads exact transitions; the
    polyfill fallback probes daily.
  • Added repeatable query-window fuzzing, direct issue and boundary regressions,
    and timezone tests covering thirteen short-lived offset regimes.
  • Validated all 1,321 tests on Node 20, 24, and 26, plus 211,200 seeded
    calendar/query comparisons and 600 numeric-query fuzz cases. Independent
    calendar reference checks complement comparisons between library paths.

Generated invalid dates and nonexistent local times are now omitted as required by RFC 5545. Explicit DTSTART/RDATE values retain their interpretation, and RFC 7529 SKIP policies remain available for calendar-date adjustment.

Audit and validation details · Full changelog