FA-76851 / Calendar recurrence rules / Open access
Weekly BYDAY expansion honouring the week-start day: in week order · case 01
With WKST=SU a Sunday instance is emitted after later weekdays, so COUNT keeps the wrong instances.
ROOT CAUSE
Weekdays inside one week are emitted in Monday-first numeric order rather than in order from WKST.
THE FAILURE
Weekdays inside one week are emitted in Monday-first numeric order rather than in order from WKST.
Unsuccessful approach: The partial repair `sorted(days, key=lambda w: (w - start.weekday()) % 7)` orders weekdays relative to the dtstart weekday, which still misorders weeks that do not begin at dtstart.
Case contract
FREQ=WEEKLY expansion. byday lists weekday numbers (0=Monday..6=Sunday); an empty list means the weekday of dtstart. Weeks begin on wkst; the week containing dtstart is week 0 and only weeks whose index is a multiple of interval are active. Instances are chronological, never before dtstart, and dtstart itself is an instance only if its weekday is listed. Return the first count ISO dates.
Why this case matters
Recurring calendar series are expanded into concrete instances for display, reminders and conflict checks.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import datetime as dt
import calendar
N = 1
observations = []
def solve(dtstart, interval, byday, wkst, count):
start = dt.date.fromisoformat(dtstart)
days = sorted(set(byday)) if byday else [start.weekday()]
week0 = start - dt.timedelta(days=(start.weekday() - wkst) % 7)
out = []
for k in range(600):
week = week0 + dt.timedelta(weeks=k * interval)
for wd in days:
d = week + dt.timedelta(days=(wd - wkst) % 7)
if d < start:
continue
if len(out) >= count:
return out
out.append(d.isoformat())
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: WKST=SU interval 2 TU,SU',
['1997-08-05', 2, [1, 6], 6, 4],
['1997-08-05', '1997-08-17', '1997-08-19', '1997-08-31']),
('regression: WKST=MO interval 2 TU,SU',
['1997-08-05', 2, [1, 6], 0, 4],
['1997-08-05', '1997-08-10', '1997-08-19', '1997-08-24']),
('non-matching dtstart Wednesday',
['2024-01-03', 1, [0, 4], 0, 3],
['2024-01-05', '2024-01-08', '2024-01-12']),
('dtstart mid-week weekly MO,WE,FR',
['2024-01-04', 1, [0, 2, 4], 0, 5],
['2024-01-05', '2024-01-08', '2024-01-10', '2024-01-12', '2024-01-15']),
('empty BYDAY uses dtstart weekday',
['2024-02-29', 3, [], 0, 3],
['2024-02-29', '2024-03-21', '2024-04-11']),
('count zero', ['2024-01-01', 1, [0], 0, 0], []),
('WKST=SU weekly SA,SU',
['2024-03-09', 1, [5, 6], 6, 4],
['2024-03-09', '2024-03-10', '2024-03-16', '2024-03-17'])],
[('non-matching dtstart Wednesday',
['2024-01-03', 1, [0, 4], 0, 3],
['2024-01-05', '2024-01-08', '2024-01-12']),
('dtstart mid-week weekly MO,WE,FR',
['2024-01-04', 1, [0, 2, 4], 0, 5],
['2024-01-05', '2024-01-08', '2024-01-10', '2024-01-12', '2024-01-15']),
('empty BYDAY uses dtstart weekday',
['2024-02-29', 3, [], 0, 3],
['2024-02-29', '2024-03-21', '2024-04-11']),
('count zero', ['2024-01-01', 1, [0], 0, 0], []),
('WKST=SU weekly SA,SU',
['2024-03-09', 1, [5, 6], 6, 4],
['2024-03-09', '2024-03-10', '2024-03-16', '2024-03-17']),
('interval 3 friday from monday', ['2024-05-06', 3, [4], 0, 3], ['2024-05-10', '2024-05-31', '2024-06-21']),
('WKST=WE interval 2 MO,TH',
['2024-06-04', 2, [0, 3], 2, 5],
['2024-06-13', '2024-06-17', '2024-06-27', '2024-07-01', '2024-07-11'])],
[('empty BYDAY uses dtstart weekday',
['2024-02-29', 3, [], 0, 3],
['2024-02-29', '2024-03-21', '2024-04-11']),
('count zero', ['2024-01-01', 1, [0], 0, 0], []),
('WKST=SU weekly SA,SU',
['2024-03-09', 1, [5, 6], 6, 4],
['2024-03-09', '2024-03-10', '2024-03-16', '2024-03-17']),
('interval 3 friday from monday', ['2024-05-06', 3, [4], 0, 3], ['2024-05-10', '2024-05-31', '2024-06-21']),
('WKST=WE interval 2 MO,TH',
['2024-06-04', 2, [0, 3], 2, 5],
['2024-06-13', '2024-06-17', '2024-06-27', '2024-07-01', '2024-07-11']),
('single sunday series', ['2024-12-29', 2, [6], 0, 3], ['2024-12-29', '2025-01-12', '2025-01-26']),
('dtstart on listed day',
['2025-01-06', 2, [0, 3], 0, 4],
['2025-01-06', '2025-01-09', '2025-01-20', '2025-01-23'])],
[('WKST=SU weekly SA,SU',
['2024-03-09', 1, [5, 6], 6, 4],
['2024-03-09', '2024-03-10', '2024-03-16', '2024-03-17']),
('interval 3 friday from monday', ['2024-05-06', 3, [4], 0, 3], ['2024-05-10', '2024-05-31', '2024-06-21']),
('WKST=WE interval 2 MO,TH',
['2024-06-04', 2, [0, 3], 2, 5],
['2024-06-13', '2024-06-17', '2024-06-27', '2024-07-01', '2024-07-11']),
('single sunday series', ['2024-12-29', 2, [6], 0, 3], ['2024-12-29', '2025-01-12', '2025-01-26']),
('dtstart on listed day',
['2025-01-06', 2, [0, 3], 0, 4],
['2025-01-06', '2025-01-09', '2025-01-20', '2025-01-23']),
('WKST=SU interval 2 from saturday',
['2025-03-01', 2, [6, 5], 6, 5],
['2025-03-01', '2025-03-09', '2025-03-15', '2025-03-23', '2025-03-29']),
('regression: WKST=SU interval 2 TU,SU',
['1997-08-05', 2, [1, 6], 6, 4],
['1997-08-05', '1997-08-17', '1997-08-19', '1997-08-31'])],
[('WKST=WE interval 2 MO,TH',
['2024-06-04', 2, [0, 3], 2, 5],
['2024-06-13', '2024-06-17', '2024-06-27', '2024-07-01', '2024-07-11']),
('single sunday series', ['2024-12-29', 2, [6], 0, 3], ['2024-12-29', '2025-01-12', '2025-01-26']),
('dtstart on listed day',
['2025-01-06', 2, [0, 3], 0, 4],
['2025-01-06', '2025-01-09', '2025-01-20', '2025-01-23']),
('WKST=SU interval 2 from saturday',
['2025-03-01', 2, [6, 5], 6, 5],
['2025-03-01', '2025-03-09', '2025-03-15', '2025-03-23', '2025-03-29']),
('regression: WKST=SU interval 2 TU,SU',
['1997-08-05', 2, [1, 6], 6, 4],
['1997-08-05', '1997-08-17', '1997-08-19', '1997-08-31']),
('regression: WKST=MO interval 2 TU,SU',
['1997-08-05', 2, [1, 6], 0, 4],
['1997-08-05', '1997-08-10', '1997-08-19', '1997-08-24']),
('non-matching dtstart Wednesday',
['2024-01-03', 1, [0, 4], 0, 3],
['2024-01-05', '2024-01-08', '2024-01-12'])]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: WKST=SU interval 2 TU,SU | ['1997-08-05', '1997-08-19', '1997-08-17', '1997-09-02'] | ['1997-08-05', '1997-08-17', '1997-08-19', '1997-08-31'] | Failed |
| regression: WKST=MO interval 2 TU,SU | ['1997-08-05', '1997-08-10', '1997-08-19', '1997-08-24'] | ['1997-08-05', '1997-08-10', '1997-08-19', '1997-08-24'] | Passed |
| non-matching dtstart Wednesday | ['2024-01-05', '2024-01-08', '2024-01-12'] | ['2024-01-05', '2024-01-08', '2024-01-12'] | Passed |
| dtstart mid-week weekly MO,WE,FR | ['2024-01-05', '2024-01-08', '2024-01-10', '2024-01-12', '2024-01-15'] | ['2024-01-05', '2024-01-08', '2024-01-10', '2024-01-12', '2024-01-15'] | Passed |
| empty BYDAY uses dtstart weekday | ['2024-02-29', '2024-03-21', '2024-04-11'] | ['2024-02-29', '2024-03-21', '2024-04-11'] | Passed |
| count zero | [] | [] | Passed |
| WKST=SU weekly SA,SU | ['2024-03-09', '2024-03-16', '2024-03-10', '2024-03-23'] | ['2024-03-09', '2024-03-10', '2024-03-16', '2024-03-17'] | Failed |
SHA-256 / 13b631c6595425088c6d7d58ced9d9da13cde866cd2fc57d78784c7a9a84b097
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import datetime as dt
import calendar
N = 1
observations = []
def solve(dtstart, interval, byday, wkst, count):
start = dt.date.fromisoformat(dtstart)
days = sorted(set(byday)) if byday else [start.weekday()]
week0 = start - dt.timedelta(days=(start.weekday() - wkst) % 7)
out = []
for k in range(600):
week = week0 + dt.timedelta(weeks=k * interval)
for wd in sorted(days, key=lambda w: (w - start.weekday()) % 7):
d = week + dt.timedelta(days=(wd - wkst) % 7)
if d < start:
continue
if len(out) >= count:
return out
out.append(d.isoformat())
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: WKST=SU interval 2 TU,SU',
['1997-08-05', 2, [1, 6], 6, 4],
['1997-08-05', '1997-08-17', '1997-08-19', '1997-08-31']),
('regression: WKST=MO interval 2 TU,SU',
['1997-08-05', 2, [1, 6], 0, 4],
['1997-08-05', '1997-08-10', '1997-08-19', '1997-08-24']),
('non-matching dtstart Wednesday',
['2024-01-03', 1, [0, 4], 0, 3],
['2024-01-05', '2024-01-08', '2024-01-12']),
('dtstart mid-week weekly MO,WE,FR',
['2024-01-04', 1, [0, 2, 4], 0, 5],
['2024-01-05', '2024-01-08', '2024-01-10', '2024-01-12', '2024-01-15']),
('empty BYDAY uses dtstart weekday',
['2024-02-29', 3, [], 0, 3],
['2024-02-29', '2024-03-21', '2024-04-11']),
('count zero', ['2024-01-01', 1, [0], 0, 0], []),
('WKST=SU weekly SA,SU',
['2024-03-09', 1, [5, 6], 6, 4],
['2024-03-09', '2024-03-10', '2024-03-16', '2024-03-17'])],
[('non-matching dtstart Wednesday',
['2024-01-03', 1, [0, 4], 0, 3],
['2024-01-05', '2024-01-08', '2024-01-12']),
('dtstart mid-week weekly MO,WE,FR',
['2024-01-04', 1, [0, 2, 4], 0, 5],
['2024-01-05', '2024-01-08', '2024-01-10', '2024-01-12', '2024-01-15']),
('empty BYDAY uses dtstart weekday',
['2024-02-29', 3, [], 0, 3],
['2024-02-29', '2024-03-21', '2024-04-11']),
('count zero', ['2024-01-01', 1, [0], 0, 0], []),
('WKST=SU weekly SA,SU',
['2024-03-09', 1, [5, 6], 6, 4],
['2024-03-09', '2024-03-10', '2024-03-16', '2024-03-17']),
('interval 3 friday from monday', ['2024-05-06', 3, [4], 0, 3], ['2024-05-10', '2024-05-31', '2024-06-21']),
('WKST=WE interval 2 MO,TH',
['2024-06-04', 2, [0, 3], 2, 5],
['2024-06-13', '2024-06-17', '2024-06-27', '2024-07-01', '2024-07-11'])],
[('empty BYDAY uses dtstart weekday',
['2024-02-29', 3, [], 0, 3],
['2024-02-29', '2024-03-21', '2024-04-11']),
('count zero', ['2024-01-01', 1, [0], 0, 0], []),
('WKST=SU weekly SA,SU',
['2024-03-09', 1, [5, 6], 6, 4],
['2024-03-09', '2024-03-10', '2024-03-16', '2024-03-17']),
('interval 3 friday from monday', ['2024-05-06', 3, [4], 0, 3], ['2024-05-10', '2024-05-31', '2024-06-21']),
('WKST=WE interval 2 MO,TH',
['2024-06-04', 2, [0, 3], 2, 5],
['2024-06-13', '2024-06-17', '2024-06-27', '2024-07-01', '2024-07-11']),
('single sunday series', ['2024-12-29', 2, [6], 0, 3], ['2024-12-29', '2025-01-12', '2025-01-26']),
('dtstart on listed day',
['2025-01-06', 2, [0, 3], 0, 4],
['2025-01-06', '2025-01-09', '2025-01-20', '2025-01-23'])],
[('WKST=SU weekly SA,SU',
['2024-03-09', 1, [5, 6], 6, 4],
['2024-03-09', '2024-03-10', '2024-03-16', '2024-03-17']),
('interval 3 friday from monday', ['2024-05-06', 3, [4], 0, 3], ['2024-05-10', '2024-05-31', '2024-06-21']),
('WKST=WE interval 2 MO,TH',
['2024-06-04', 2, [0, 3], 2, 5],
['2024-06-13', '2024-06-17', '2024-06-27', '2024-07-01', '2024-07-11']),
('single sunday series', ['2024-12-29', 2, [6], 0, 3], ['2024-12-29', '2025-01-12', '2025-01-26']),
('dtstart on listed day',
['2025-01-06', 2, [0, 3], 0, 4],
['2025-01-06', '2025-01-09', '2025-01-20', '2025-01-23']),
('WKST=SU interval 2 from saturday',
['2025-03-01', 2, [6, 5], 6, 5],
['2025-03-01', '2025-03-09', '2025-03-15', '2025-03-23', '2025-03-29']),
('regression: WKST=SU interval 2 TU,SU',
['1997-08-05', 2, [1, 6], 6, 4],
['1997-08-05', '1997-08-17', '1997-08-19', '1997-08-31'])],
[('WKST=WE interval 2 MO,TH',
['2024-06-04', 2, [0, 3], 2, 5],
['2024-06-13', '2024-06-17', '2024-06-27', '2024-07-01', '2024-07-11']),
('single sunday series', ['2024-12-29', 2, [6], 0, 3], ['2024-12-29', '2025-01-12', '2025-01-26']),
('dtstart on listed day',
['2025-01-06', 2, [0, 3], 0, 4],
['2025-01-06', '2025-01-09', '2025-01-20', '2025-01-23']),
('WKST=SU interval 2 from saturday',
['2025-03-01', 2, [6, 5], 6, 5],
['2025-03-01', '2025-03-09', '2025-03-15', '2025-03-23', '2025-03-29']),
('regression: WKST=SU interval 2 TU,SU',
['1997-08-05', 2, [1, 6], 6, 4],
['1997-08-05', '1997-08-17', '1997-08-19', '1997-08-31']),
('regression: WKST=MO interval 2 TU,SU',
['1997-08-05', 2, [1, 6], 0, 4],
['1997-08-05', '1997-08-10', '1997-08-19', '1997-08-24']),
('non-matching dtstart Wednesday',
['2024-01-03', 1, [0, 4], 0, 3],
['2024-01-05', '2024-01-08', '2024-01-12'])]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: WKST=SU interval 2 TU,SU | ['1997-08-05', '1997-08-19', '1997-08-17', '1997-09-02'] | ['1997-08-05', '1997-08-17', '1997-08-19', '1997-08-31'] | Failed |
| regression: WKST=MO interval 2 TU,SU | ['1997-08-05', '1997-08-10', '1997-08-19', '1997-08-24'] | ['1997-08-05', '1997-08-10', '1997-08-19', '1997-08-24'] | Passed |
| non-matching dtstart Wednesday | ['2024-01-05', '2024-01-12', '2024-01-08'] | ['2024-01-05', '2024-01-08', '2024-01-12'] | Failed |
| dtstart mid-week weekly MO,WE,FR | ['2024-01-05', '2024-01-12', '2024-01-08', '2024-01-10', '2024-01-19'] | ['2024-01-05', '2024-01-08', '2024-01-10', '2024-01-12', '2024-01-15'] | Failed |
| empty BYDAY uses dtstart weekday | ['2024-02-29', '2024-03-21', '2024-04-11'] | ['2024-02-29', '2024-03-21', '2024-04-11'] | Passed |
| count zero | [] | [] | Passed |
| WKST=SU weekly SA,SU | ['2024-03-09', '2024-03-16', '2024-03-10', '2024-03-23'] | ['2024-03-09', '2024-03-10', '2024-03-16', '2024-03-17'] | Failed |
SHA-256 / 5771c9f3ee1b9734804d93eaf6f1bbe245c5a7bd36f2dd305e5a566775ea111e
HELD IN THE MEMBER ARCHIVE
The verified repair and its recorded checks are member-only.
This mechanism has 7 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.
Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.
Member access is invitation-based. Sign in with your invited account to inspect the repair.
Sign in to the archive ↗Verification & scope
Stipulated, bounded recurrence-expansion model evaluated offline on explicit fixtures; it is not a complete iCalendar implementation and makes no claim of standards conformance. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:49:20.033858+00:00.
Case digest / 2225ca40dd84ddf916668b8ad75556c9be4295aba30bafb147f9dcfb4db36872