FA-77131 / Calendar recurrence rules / Open access
Yearly ISO BYWEEKNO/BYDAY expansion: day offset · case 01
BYWEEKNO=20;BYDAY=MO produces Tuesdays.
ROOT CAUSE
Weekday numbers are added as if Monday were 1.
VERIFIED REPAIR
At the day offset decision use `(w - 1) * 7 + wd`, leaving the other decision sites of the model unchanged.
Unsuccessful approach: The partial repair `(w - 1) * 7 + (wd + 1) % 7` rotates Sunday to the start of the week.
Case contract
FREQ=YEARLY with BYWEEKNO (ISO weeks, Monday start, week 1 contains January 4) and BYDAY weekdays (0=Monday). Negative week numbers count from the last ISO week of the year (-1 is the last). A year has 53 weeks exactly when December 28 falls in week 53; week numbers outside 1..weeks are ignored for that year. Dates may fall in the adjacent calendar year. Expand years year_start .. year_start+years-1 and return unique ISO dates sorted.
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(year_start, weeknos, weekdays, years):
out = set()
for y in range(year_start, year_start + years):
jan4 = dt.date(y, 1, 4)
week1 = jan4 - dt.timedelta(days=jan4.weekday())
nweeks = dt.date(y, 12, 28).isocalendar()[1]
for wn in weeknos:
w = wn if wn > 0 else nweeks + wn + 1
if not (1 <= w <= nweeks):
continue
for wd in weekdays:
out.add(week1 + dt.timedelta(days=(w - 1) * 7 + wd + 1))
return sorted(d.isoformat() for d in out)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: week 1 in 2021', [2021, [1], [0], 1], ['2021-01-04']),
('week 53 existence', [2019, [53], [0], 3], ['2020-12-28']),
('last week negative', [2020, [-1], [6], 3], ['2021-01-03', '2022-01-02', '2023-01-01']),
('leap year starting wednesday', [2024, [-1, 53], [0], 2], ['2024-12-23', '2025-12-22']),
('week 20 monday friday',
[2023, [20], [0, 4], 2],
['2023-05-15', '2023-05-19', '2024-05-13', '2024-05-17']),
('too-negative week', [2021, [-60, 2], [2], 1], ['2021-01-13']),
('week 1 sunday spans years',
[2015, [1, 52], [6], 2],
['2015-01-04', '2015-12-27', '2016-01-10', '2017-01-01'])],
[('last week negative', [2020, [-1], [6], 3], ['2021-01-03', '2022-01-02', '2023-01-01']),
('leap year starting wednesday', [2024, [-1, 53], [0], 2], ['2024-12-23', '2025-12-22']),
('week 20 monday friday',
[2023, [20], [0, 4], 2],
['2023-05-15', '2023-05-19', '2024-05-13', '2024-05-17']),
('too-negative week', [2021, [-60, 2], [2], 1], ['2021-01-13']),
('week 1 sunday spans years',
[2015, [1, 52], [6], 2],
['2015-01-04', '2015-12-27', '2016-01-10', '2017-01-01']),
('second to last week', [2026, [-2], [3], 2], ['2026-12-24', '2027-12-23']),
('many weeks', [2027, [1, -1, 26], [0], 1], ['2027-01-04', '2027-06-28', '2027-12-27'])],
[('week 20 monday friday',
[2023, [20], [0, 4], 2],
['2023-05-15', '2023-05-19', '2024-05-13', '2024-05-17']),
('too-negative week', [2021, [-60, 2], [2], 1], ['2021-01-13']),
('week 1 sunday spans years',
[2015, [1, 52], [6], 2],
['2015-01-04', '2015-12-27', '2016-01-10', '2017-01-01']),
('second to last week', [2026, [-2], [3], 2], ['2026-12-24', '2027-12-23']),
('many weeks', [2027, [1, -1, 26], [0], 1], ['2027-01-04', '2027-06-28', '2027-12-27']),
('year starting saturday', [2022, [1, 53], [1, 5], 1], ['2022-01-04', '2022-01-08']),
('53 in 2026', [2026, [53], [4], 1], ['2027-01-01'])],
[('week 1 sunday spans years',
[2015, [1, 52], [6], 2],
['2015-01-04', '2015-12-27', '2016-01-10', '2017-01-01']),
('second to last week', [2026, [-2], [3], 2], ['2026-12-24', '2027-12-23']),
('many weeks', [2027, [1, -1, 26], [0], 1], ['2027-01-04', '2027-06-28', '2027-12-27']),
('year starting saturday', [2022, [1, 53], [1, 5], 1], ['2022-01-04', '2022-01-08']),
('53 in 2026', [2026, [53], [4], 1], ['2027-01-01']),
('regression: week 1 in 2021', [2021, [1], [0], 1], ['2021-01-04']),
('week 53 existence', [2019, [53], [0], 3], ['2020-12-28'])],
[('many weeks', [2027, [1, -1, 26], [0], 1], ['2027-01-04', '2027-06-28', '2027-12-27']),
('year starting saturday', [2022, [1, 53], [1, 5], 1], ['2022-01-04', '2022-01-08']),
('53 in 2026', [2026, [53], [4], 1], ['2027-01-01']),
('regression: week 1 in 2021', [2021, [1], [0], 1], ['2021-01-04']),
('week 53 existence', [2019, [53], [0], 3], ['2020-12-28']),
('last week negative', [2020, [-1], [6], 3], ['2021-01-03', '2022-01-02', '2023-01-01']),
('leap year starting wednesday', [2024, [-1, 53], [0], 2], ['2024-12-23', '2025-12-22'])]]
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: week 1 in 2021 | ['2021-01-05'] | ['2021-01-04'] | Failed |
| week 53 existence | ['2020-12-29'] | ['2020-12-28'] | Failed |
| last week negative | ['2021-01-04', '2022-01-03', '2023-01-02'] | ['2021-01-03', '2022-01-02', '2023-01-01'] | Failed |
| leap year starting wednesday | ['2024-12-24', '2025-12-23'] | ['2024-12-23', '2025-12-22'] | Failed |
| week 20 monday friday | ['2023-05-16', '2023-05-20', '2024-05-14', '2024-05-18'] | ['2023-05-15', '2023-05-19', '2024-05-13', '2024-05-17'] | Failed |
| too-negative week | ['2021-01-14'] | ['2021-01-13'] | Failed |
| week 1 sunday spans years | ['2015-01-05', '2015-12-28', '2016-01-11', '2017-01-02'] | ['2015-01-04', '2015-12-27', '2016-01-10', '2017-01-01'] | Failed |
SHA-256 / 18e38aec98b426decfaf6aad9bcea95fb56a3c4ffaea630dbcdec5db74b63231
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(year_start, weeknos, weekdays, years):
out = set()
for y in range(year_start, year_start + years):
jan4 = dt.date(y, 1, 4)
week1 = jan4 - dt.timedelta(days=jan4.weekday())
nweeks = dt.date(y, 12, 28).isocalendar()[1]
for wn in weeknos:
w = wn if wn > 0 else nweeks + wn + 1
if not (1 <= w <= nweeks):
continue
for wd in weekdays:
out.add(week1 + dt.timedelta(days=(w - 1) * 7 + (wd + 1) % 7))
return sorted(d.isoformat() for d in out)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: week 1 in 2021', [2021, [1], [0], 1], ['2021-01-04']),
('week 53 existence', [2019, [53], [0], 3], ['2020-12-28']),
('last week negative', [2020, [-1], [6], 3], ['2021-01-03', '2022-01-02', '2023-01-01']),
('leap year starting wednesday', [2024, [-1, 53], [0], 2], ['2024-12-23', '2025-12-22']),
('week 20 monday friday',
[2023, [20], [0, 4], 2],
['2023-05-15', '2023-05-19', '2024-05-13', '2024-05-17']),
('too-negative week', [2021, [-60, 2], [2], 1], ['2021-01-13']),
('week 1 sunday spans years',
[2015, [1, 52], [6], 2],
['2015-01-04', '2015-12-27', '2016-01-10', '2017-01-01'])],
[('last week negative', [2020, [-1], [6], 3], ['2021-01-03', '2022-01-02', '2023-01-01']),
('leap year starting wednesday', [2024, [-1, 53], [0], 2], ['2024-12-23', '2025-12-22']),
('week 20 monday friday',
[2023, [20], [0, 4], 2],
['2023-05-15', '2023-05-19', '2024-05-13', '2024-05-17']),
('too-negative week', [2021, [-60, 2], [2], 1], ['2021-01-13']),
('week 1 sunday spans years',
[2015, [1, 52], [6], 2],
['2015-01-04', '2015-12-27', '2016-01-10', '2017-01-01']),
('second to last week', [2026, [-2], [3], 2], ['2026-12-24', '2027-12-23']),
('many weeks', [2027, [1, -1, 26], [0], 1], ['2027-01-04', '2027-06-28', '2027-12-27'])],
[('week 20 monday friday',
[2023, [20], [0, 4], 2],
['2023-05-15', '2023-05-19', '2024-05-13', '2024-05-17']),
('too-negative week', [2021, [-60, 2], [2], 1], ['2021-01-13']),
('week 1 sunday spans years',
[2015, [1, 52], [6], 2],
['2015-01-04', '2015-12-27', '2016-01-10', '2017-01-01']),
('second to last week', [2026, [-2], [3], 2], ['2026-12-24', '2027-12-23']),
('many weeks', [2027, [1, -1, 26], [0], 1], ['2027-01-04', '2027-06-28', '2027-12-27']),
('year starting saturday', [2022, [1, 53], [1, 5], 1], ['2022-01-04', '2022-01-08']),
('53 in 2026', [2026, [53], [4], 1], ['2027-01-01'])],
[('week 1 sunday spans years',
[2015, [1, 52], [6], 2],
['2015-01-04', '2015-12-27', '2016-01-10', '2017-01-01']),
('second to last week', [2026, [-2], [3], 2], ['2026-12-24', '2027-12-23']),
('many weeks', [2027, [1, -1, 26], [0], 1], ['2027-01-04', '2027-06-28', '2027-12-27']),
('year starting saturday', [2022, [1, 53], [1, 5], 1], ['2022-01-04', '2022-01-08']),
('53 in 2026', [2026, [53], [4], 1], ['2027-01-01']),
('regression: week 1 in 2021', [2021, [1], [0], 1], ['2021-01-04']),
('week 53 existence', [2019, [53], [0], 3], ['2020-12-28'])],
[('many weeks', [2027, [1, -1, 26], [0], 1], ['2027-01-04', '2027-06-28', '2027-12-27']),
('year starting saturday', [2022, [1, 53], [1, 5], 1], ['2022-01-04', '2022-01-08']),
('53 in 2026', [2026, [53], [4], 1], ['2027-01-01']),
('regression: week 1 in 2021', [2021, [1], [0], 1], ['2021-01-04']),
('week 53 existence', [2019, [53], [0], 3], ['2020-12-28']),
('last week negative', [2020, [-1], [6], 3], ['2021-01-03', '2022-01-02', '2023-01-01']),
('leap year starting wednesday', [2024, [-1, 53], [0], 2], ['2024-12-23', '2025-12-22'])]]
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: week 1 in 2021 | ['2021-01-05'] | ['2021-01-04'] | Failed |
| week 53 existence | ['2020-12-29'] | ['2020-12-28'] | Failed |
| last week negative | ['2020-12-28', '2021-12-27', '2022-12-26'] | ['2021-01-03', '2022-01-02', '2023-01-01'] | Failed |
| leap year starting wednesday | ['2024-12-24', '2025-12-23'] | ['2024-12-23', '2025-12-22'] | Failed |
| week 20 monday friday | ['2023-05-16', '2023-05-20', '2024-05-14', '2024-05-18'] | ['2023-05-15', '2023-05-19', '2024-05-13', '2024-05-17'] | Failed |
| too-negative week | ['2021-01-14'] | ['2021-01-13'] | Failed |
| week 1 sunday spans years | ['2014-12-29', '2015-12-21', '2016-01-04', '2016-12-26'] | ['2015-01-04', '2015-12-27', '2016-01-10', '2017-01-01'] | Failed |
SHA-256 / c7c0e2e0e420413e7192f148d2bbc73403dd62f757b5d51b0fef76a4681ffa79
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import datetime as dt
import calendar
N = 1
observations = []
def solve(year_start, weeknos, weekdays, years):
out = set()
for y in range(year_start, year_start + years):
jan4 = dt.date(y, 1, 4)
week1 = jan4 - dt.timedelta(days=jan4.weekday())
nweeks = dt.date(y, 12, 28).isocalendar()[1]
for wn in weeknos:
w = wn if wn > 0 else nweeks + wn + 1
if not (1 <= w <= nweeks):
continue
for wd in weekdays:
out.add(week1 + dt.timedelta(days=(w - 1) * 7 + wd))
return sorted(d.isoformat() for d in out)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: week 1 in 2021', [2021, [1], [0], 1], ['2021-01-04']),
('week 53 existence', [2019, [53], [0], 3], ['2020-12-28']),
('last week negative', [2020, [-1], [6], 3], ['2021-01-03', '2022-01-02', '2023-01-01']),
('leap year starting wednesday', [2024, [-1, 53], [0], 2], ['2024-12-23', '2025-12-22']),
('week 20 monday friday',
[2023, [20], [0, 4], 2],
['2023-05-15', '2023-05-19', '2024-05-13', '2024-05-17']),
('too-negative week', [2021, [-60, 2], [2], 1], ['2021-01-13']),
('week 1 sunday spans years',
[2015, [1, 52], [6], 2],
['2015-01-04', '2015-12-27', '2016-01-10', '2017-01-01'])],
[('last week negative', [2020, [-1], [6], 3], ['2021-01-03', '2022-01-02', '2023-01-01']),
('leap year starting wednesday', [2024, [-1, 53], [0], 2], ['2024-12-23', '2025-12-22']),
('week 20 monday friday',
[2023, [20], [0, 4], 2],
['2023-05-15', '2023-05-19', '2024-05-13', '2024-05-17']),
('too-negative week', [2021, [-60, 2], [2], 1], ['2021-01-13']),
('week 1 sunday spans years',
[2015, [1, 52], [6], 2],
['2015-01-04', '2015-12-27', '2016-01-10', '2017-01-01']),
('second to last week', [2026, [-2], [3], 2], ['2026-12-24', '2027-12-23']),
('many weeks', [2027, [1, -1, 26], [0], 1], ['2027-01-04', '2027-06-28', '2027-12-27'])],
[('week 20 monday friday',
[2023, [20], [0, 4], 2],
['2023-05-15', '2023-05-19', '2024-05-13', '2024-05-17']),
('too-negative week', [2021, [-60, 2], [2], 1], ['2021-01-13']),
('week 1 sunday spans years',
[2015, [1, 52], [6], 2],
['2015-01-04', '2015-12-27', '2016-01-10', '2017-01-01']),
('second to last week', [2026, [-2], [3], 2], ['2026-12-24', '2027-12-23']),
('many weeks', [2027, [1, -1, 26], [0], 1], ['2027-01-04', '2027-06-28', '2027-12-27']),
('year starting saturday', [2022, [1, 53], [1, 5], 1], ['2022-01-04', '2022-01-08']),
('53 in 2026', [2026, [53], [4], 1], ['2027-01-01'])],
[('week 1 sunday spans years',
[2015, [1, 52], [6], 2],
['2015-01-04', '2015-12-27', '2016-01-10', '2017-01-01']),
('second to last week', [2026, [-2], [3], 2], ['2026-12-24', '2027-12-23']),
('many weeks', [2027, [1, -1, 26], [0], 1], ['2027-01-04', '2027-06-28', '2027-12-27']),
('year starting saturday', [2022, [1, 53], [1, 5], 1], ['2022-01-04', '2022-01-08']),
('53 in 2026', [2026, [53], [4], 1], ['2027-01-01']),
('regression: week 1 in 2021', [2021, [1], [0], 1], ['2021-01-04']),
('week 53 existence', [2019, [53], [0], 3], ['2020-12-28'])],
[('many weeks', [2027, [1, -1, 26], [0], 1], ['2027-01-04', '2027-06-28', '2027-12-27']),
('year starting saturday', [2022, [1, 53], [1, 5], 1], ['2022-01-04', '2022-01-08']),
('53 in 2026', [2026, [53], [4], 1], ['2027-01-01']),
('regression: week 1 in 2021', [2021, [1], [0], 1], ['2021-01-04']),
('week 53 existence', [2019, [53], [0], 3], ['2020-12-28']),
('last week negative', [2020, [-1], [6], 3], ['2021-01-03', '2022-01-02', '2023-01-01']),
('leap year starting wednesday', [2024, [-1, 53], [0], 2], ['2024-12-23', '2025-12-22'])]]
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: week 1 in 2021 | ['2021-01-04'] | ['2021-01-04'] | Passed |
| week 53 existence | ['2020-12-28'] | ['2020-12-28'] | Passed |
| last week negative | ['2021-01-03', '2022-01-02', '2023-01-01'] | ['2021-01-03', '2022-01-02', '2023-01-01'] | Passed |
| leap year starting wednesday | ['2024-12-23', '2025-12-22'] | ['2024-12-23', '2025-12-22'] | Passed |
| week 20 monday friday | ['2023-05-15', '2023-05-19', '2024-05-13', '2024-05-17'] | ['2023-05-15', '2023-05-19', '2024-05-13', '2024-05-17'] | Passed |
| too-negative week | ['2021-01-13'] | ['2021-01-13'] | Passed |
| week 1 sunday spans years | ['2015-01-04', '2015-12-27', '2016-01-10', '2017-01-01'] | ['2015-01-04', '2015-12-27', '2016-01-10', '2017-01-01'] | Passed |
SHA-256 / 1bf8675221608a6eaa01e46aef10b50753f45fd6b34db88f615e16221044d69e
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:22.593674+00:00.
Case digest / be2aefd6d50a6307148e6982eb2b432ca3bfd848d4440ed961ceb13916f52820