Recurrence: MONTHLY/YEARLY silently skip short months / non-leap years (month-end policy) #12

Closed
opened 2026-06-05 10:26:18 +00:00 by victor · 0 comments
Owner

When BYMONTHDAY is absent, the target day defaults to anchor.day() (src/core/recurrence.rs:240,274). NaiveDate::from_ymd_opt returns None for invalid days and the loop just advances, skipping that month/year entirely.

Consequences:

  • Anchor Jan 31, FREQ=MONTHLY → next after Jan 31 is Mar 31 (February skipped), not Feb 28.
  • Anchor Feb 29 2024, FREQ=YEARLY → next is Feb 29 2028 (2025-27 skipped).

This is inconsistent with apply_snap DayOfMonth, which clamps to month-end (recurrence.rs:63-67).

Decision needed (spec): clamp the target day to the last day of the month (recommended — conventional "monthly on the 31st" = month-end, and consistent with the snap behavior) vs. the current skip. REQUIREMENTS §7 should state the chosen policy. Then implement + test the Jan 31 and Feb 29 cases.

Found in review.

When BYMONTHDAY is absent, the target day defaults to `anchor.day()` (src/core/recurrence.rs:240,274). `NaiveDate::from_ymd_opt` returns None for invalid days and the loop just advances, **skipping** that month/year entirely. **Consequences:** - Anchor Jan 31, `FREQ=MONTHLY` → next after Jan 31 is **Mar 31** (February skipped), not Feb 28. - Anchor Feb 29 2024, `FREQ=YEARLY` → next is **Feb 29 2028** (2025-27 skipped). This is inconsistent with `apply_snap` `DayOfMonth`, which **clamps** to month-end (recurrence.rs:63-67). **Decision needed (spec):** clamp the target day to the last day of the month (recommended — conventional "monthly on the 31st" = month-end, and consistent with the snap behavior) vs. the current skip. REQUIREMENTS §7 should state the chosen policy. Then implement + test the Jan 31 and Feb 29 cases. Found in review.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
victor/task-manager#12
No description provided.