FA-77406 / Legal deadline computation / Open access
Month-denominated periods with end-of-month rule: missing day · case 01
A one-month period from January 30 overflows into March.
ROOT CAUSE
A missing day is added as an offset from the first, overflowing into the next month.
VERIFIED REPAIR
At the missing day decision use `min(t.day, dim)`, leaving the other decision sites of the model unchanged.
Unsuccessful approach: The partial repair `min(t.day, 28)` caps every day at 28, shortening periods in long months.
Case contract
A period of months runs to the same-numbered day of the target month. Stipulated: if the trigger is the last day of its month the period ends on the last day of the target month; otherwise a missing day (e.g. the 30th of February) becomes the last day of the target month. A closed last day (Saturday, Sunday, listed holiday) moves forward to the next open day, even into the next month.
Why this case matters
Docketing systems compute filing and response deadlines from trigger events; a wrong date can forfeit a right.
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(trigger, months, holidays):
t = dt.date.fromisoformat(trigger)
hol = {dt.date.fromisoformat(x) for x in holidays}
mi = t.month - 1 + months
y, m = t.year + mi // 12, mi % 12 + 1
dim = calendar.monthrange(y, m)[1]
eom = t.day == calendar.monthrange(t.year, t.month)[1]
day = dim if eom else t.day
d = dt.date(y, m, 1) + dt.timedelta(days=day - 1)
while d.weekday() >= 5 or d in hol:
d += dt.timedelta(days=1)
return d.isoformat()
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: jan 30 plus one month', ['2023-01-30', 1, []], '2023-02-28'),
('month end april to may',
['2024-04-30',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-31'),
('month end feb common', ['2023-02-28', 1, []], '2023-03-31'),
('month end feb leap to march',
['2024-02-29',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-04-01'),
('lands saturday month end',
['2024-05-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-09-03'),
('lands sunday mid month',
['2024-01-14',
6,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-15'),
('twelve months from leap day', ['2024-02-29', 12, []], '2025-02-28'),
('day 29 two months',
['2024-01-29',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-03-29')],
[('month end feb common', ['2023-02-28', 1, []], '2023-03-31'),
('month end feb leap to march',
['2024-02-29',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-04-01'),
('lands saturday month end',
['2024-05-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-09-03'),
('lands sunday mid month',
['2024-01-14',
6,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-15'),
('twelve months from leap day', ['2024-02-29', 12, []], '2025-02-28'),
('lands on holiday',
['2024-04-04',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-05'),
('jan 31 plus one',
['2024-01-31',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-02-29'),
('day 30 to may',
['2024-01-30',
4,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-30'),
('regression: jan 30 plus one month', ['2023-01-30', 1, []], '2023-02-28')],
[('lands saturday month end',
['2024-05-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-09-03'),
('lands sunday mid month',
['2024-01-14',
6,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-15'),
('twelve months from leap day', ['2024-02-29', 12, []], '2025-02-28'),
('lands on holiday',
['2024-04-04',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-05'),
('jan 31 plus one',
['2024-01-31',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-02-29'),
('mid month simple',
['2024-03-12',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-13'),
('aug 31 to nov 30 saturday',
['2024-08-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-12-02'),
('day 29 two months',
['2024-01-29',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-03-29'),
('regression: jan 30 plus one month', ['2023-01-30', 1, []], '2023-02-28')],
[('twelve months from leap day', ['2024-02-29', 12, []], '2025-02-28'),
('lands on holiday',
['2024-04-04',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-05'),
('jan 31 plus one',
['2024-01-31',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-02-29'),
('mid month simple',
['2024-03-12',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-13'),
('aug 31 to nov 30 saturday',
['2024-08-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-12-02'),
('day 29 two months',
['2024-01-29',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-03-29'),
('day 30 to may',
['2024-01-30',
4,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-30'),
('regression: jan 30 plus one month', ['2023-01-30', 1, []], '2023-02-28')],
[('jan 31 plus one',
['2024-01-31',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-02-29'),
('mid month simple',
['2024-03-12',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-13'),
('aug 31 to nov 30 saturday',
['2024-08-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-12-02'),
('day 29 two months',
['2024-01-29',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-03-29'),
('day 30 to may',
['2024-01-30',
4,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-30'),
('regression: jan 30 plus one month', ['2023-01-30', 1, []], '2023-02-28'),
('month end april to may',
['2024-04-30',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-31')]]
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: jan 30 plus one month | 2023-03-02 | 2023-02-28 | Failed |
| month end april to may | 2024-05-31 | 2024-05-31 | Passed |
| month end feb common | 2023-03-31 | 2023-03-31 | Passed |
| month end feb leap to march | 2024-04-01 | 2024-04-01 | Passed |
| lands saturday month end | 2024-09-03 | 2024-09-03 | Passed |
| lands sunday mid month | 2024-07-15 | 2024-07-15 | Passed |
| twelve months from leap day | 2025-02-28 | 2025-02-28 | Passed |
| day 29 two months | 2024-03-29 | 2024-03-29 | Passed |
SHA-256 / e35dd8422a8550a262abfb4baf3cb3966bf1e3ad61173f91fb49babffcbc7c4d
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(trigger, months, holidays):
t = dt.date.fromisoformat(trigger)
hol = {dt.date.fromisoformat(x) for x in holidays}
mi = t.month - 1 + months
y, m = t.year + mi // 12, mi % 12 + 1
dim = calendar.monthrange(y, m)[1]
eom = t.day == calendar.monthrange(t.year, t.month)[1]
day = dim if eom else min(t.day, 28)
d = dt.date(y, m, 1) + dt.timedelta(days=day - 1)
while d.weekday() >= 5 or d in hol:
d += dt.timedelta(days=1)
return d.isoformat()
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: jan 30 plus one month', ['2023-01-30', 1, []], '2023-02-28'),
('month end april to may',
['2024-04-30',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-31'),
('month end feb common', ['2023-02-28', 1, []], '2023-03-31'),
('month end feb leap to march',
['2024-02-29',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-04-01'),
('lands saturday month end',
['2024-05-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-09-03'),
('lands sunday mid month',
['2024-01-14',
6,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-15'),
('twelve months from leap day', ['2024-02-29', 12, []], '2025-02-28'),
('day 29 two months',
['2024-01-29',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-03-29')],
[('month end feb common', ['2023-02-28', 1, []], '2023-03-31'),
('month end feb leap to march',
['2024-02-29',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-04-01'),
('lands saturday month end',
['2024-05-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-09-03'),
('lands sunday mid month',
['2024-01-14',
6,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-15'),
('twelve months from leap day', ['2024-02-29', 12, []], '2025-02-28'),
('lands on holiday',
['2024-04-04',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-05'),
('jan 31 plus one',
['2024-01-31',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-02-29'),
('day 30 to may',
['2024-01-30',
4,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-30'),
('regression: jan 30 plus one month', ['2023-01-30', 1, []], '2023-02-28')],
[('lands saturday month end',
['2024-05-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-09-03'),
('lands sunday mid month',
['2024-01-14',
6,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-15'),
('twelve months from leap day', ['2024-02-29', 12, []], '2025-02-28'),
('lands on holiday',
['2024-04-04',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-05'),
('jan 31 plus one',
['2024-01-31',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-02-29'),
('mid month simple',
['2024-03-12',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-13'),
('aug 31 to nov 30 saturday',
['2024-08-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-12-02'),
('day 29 two months',
['2024-01-29',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-03-29'),
('regression: jan 30 plus one month', ['2023-01-30', 1, []], '2023-02-28')],
[('twelve months from leap day', ['2024-02-29', 12, []], '2025-02-28'),
('lands on holiday',
['2024-04-04',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-05'),
('jan 31 plus one',
['2024-01-31',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-02-29'),
('mid month simple',
['2024-03-12',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-13'),
('aug 31 to nov 30 saturday',
['2024-08-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-12-02'),
('day 29 two months',
['2024-01-29',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-03-29'),
('day 30 to may',
['2024-01-30',
4,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-30'),
('regression: jan 30 plus one month', ['2023-01-30', 1, []], '2023-02-28')],
[('jan 31 plus one',
['2024-01-31',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-02-29'),
('mid month simple',
['2024-03-12',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-13'),
('aug 31 to nov 30 saturday',
['2024-08-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-12-02'),
('day 29 two months',
['2024-01-29',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-03-29'),
('day 30 to may',
['2024-01-30',
4,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-30'),
('regression: jan 30 plus one month', ['2023-01-30', 1, []], '2023-02-28'),
('month end april to may',
['2024-04-30',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-31')]]
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: jan 30 plus one month | 2023-02-28 | 2023-02-28 | Passed |
| month end april to may | 2024-05-31 | 2024-05-31 | Passed |
| month end feb common | 2023-03-31 | 2023-03-31 | Passed |
| month end feb leap to march | 2024-04-01 | 2024-04-01 | Passed |
| lands saturday month end | 2024-09-03 | 2024-09-03 | Passed |
| lands sunday mid month | 2024-07-15 | 2024-07-15 | Passed |
| twelve months from leap day | 2025-02-28 | 2025-02-28 | Passed |
| day 29 two months | 2024-03-28 | 2024-03-29 | Failed |
SHA-256 / aebfbdf78807c9cd1267607071c2edc7fbbe181bc91354b837f435057c5e2cd0
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(trigger, months, holidays):
t = dt.date.fromisoformat(trigger)
hol = {dt.date.fromisoformat(x) for x in holidays}
mi = t.month - 1 + months
y, m = t.year + mi // 12, mi % 12 + 1
dim = calendar.monthrange(y, m)[1]
eom = t.day == calendar.monthrange(t.year, t.month)[1]
day = dim if eom else min(t.day, dim)
d = dt.date(y, m, 1) + dt.timedelta(days=day - 1)
while d.weekday() >= 5 or d in hol:
d += dt.timedelta(days=1)
return d.isoformat()
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: jan 30 plus one month', ['2023-01-30', 1, []], '2023-02-28'),
('month end april to may',
['2024-04-30',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-31'),
('month end feb common', ['2023-02-28', 1, []], '2023-03-31'),
('month end feb leap to march',
['2024-02-29',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-04-01'),
('lands saturday month end',
['2024-05-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-09-03'),
('lands sunday mid month',
['2024-01-14',
6,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-15'),
('twelve months from leap day', ['2024-02-29', 12, []], '2025-02-28'),
('day 29 two months',
['2024-01-29',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-03-29')],
[('month end feb common', ['2023-02-28', 1, []], '2023-03-31'),
('month end feb leap to march',
['2024-02-29',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-04-01'),
('lands saturday month end',
['2024-05-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-09-03'),
('lands sunday mid month',
['2024-01-14',
6,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-15'),
('twelve months from leap day', ['2024-02-29', 12, []], '2025-02-28'),
('lands on holiday',
['2024-04-04',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-05'),
('jan 31 plus one',
['2024-01-31',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-02-29'),
('day 30 to may',
['2024-01-30',
4,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-30'),
('regression: jan 30 plus one month', ['2023-01-30', 1, []], '2023-02-28')],
[('lands saturday month end',
['2024-05-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-09-03'),
('lands sunday mid month',
['2024-01-14',
6,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-15'),
('twelve months from leap day', ['2024-02-29', 12, []], '2025-02-28'),
('lands on holiday',
['2024-04-04',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-05'),
('jan 31 plus one',
['2024-01-31',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-02-29'),
('mid month simple',
['2024-03-12',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-13'),
('aug 31 to nov 30 saturday',
['2024-08-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-12-02'),
('day 29 two months',
['2024-01-29',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-03-29'),
('regression: jan 30 plus one month', ['2023-01-30', 1, []], '2023-02-28')],
[('twelve months from leap day', ['2024-02-29', 12, []], '2025-02-28'),
('lands on holiday',
['2024-04-04',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-07-05'),
('jan 31 plus one',
['2024-01-31',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-02-29'),
('mid month simple',
['2024-03-12',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-13'),
('aug 31 to nov 30 saturday',
['2024-08-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-12-02'),
('day 29 two months',
['2024-01-29',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-03-29'),
('day 30 to may',
['2024-01-30',
4,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-30'),
('regression: jan 30 plus one month', ['2023-01-30', 1, []], '2023-02-28')],
[('jan 31 plus one',
['2024-01-31',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-02-29'),
('mid month simple',
['2024-03-12',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-13'),
('aug 31 to nov 30 saturday',
['2024-08-31',
3,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-12-02'),
('day 29 two months',
['2024-01-29',
2,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-03-29'),
('day 30 to may',
['2024-01-30',
4,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-30'),
('regression: jan 30 plus one month', ['2023-01-30', 1, []], '2023-02-28'),
('month end april to may',
['2024-04-30',
1,
['2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-06-19',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25']],
'2024-05-31')]]
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: jan 30 plus one month | 2023-02-28 | 2023-02-28 | Passed |
| month end april to may | 2024-05-31 | 2024-05-31 | Passed |
| month end feb common | 2023-03-31 | 2023-03-31 | Passed |
| month end feb leap to march | 2024-04-01 | 2024-04-01 | Passed |
| lands saturday month end | 2024-09-03 | 2024-09-03 | Passed |
| lands sunday mid month | 2024-07-15 | 2024-07-15 | Passed |
| twelve months from leap day | 2025-02-28 | 2025-02-28 | Passed |
| day 29 two months | 2024-03-29 | 2024-03-29 | Passed |
SHA-256 / 1566c23e67845402d23a5cb60becbf9795958ed41df1b397b24c97f4024b8ddf
Verification & scope
Stipulated toy deadline rules evaluated offline on explicit fixtures. The contract is inspired by common court-rule structures but is not legal advice and makes no claim to reproduce any jurisdiction's rules. 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:25.191826+00:00.
Case digest / 2ee717d7ed926e55d255b4aeff4fc0d8b2f4a588eff940427587a882b1b9ed34