{"abstract":"A month offset expressed as thirty days lands on the wrong date, or a blanket day cap loses valid month-end days.","category":"Calendar arithmetic","checks":8,"contract":"Given a valid ISO calendar date and an integer month offset, return an ISO date in the destination month, keeping the original day when possible and otherwise clamping once to the last day. Supported results stay within years 1 through 9999.","evaluation_group":"model-4f61d395a926fc7d","failed_approach":"Capping every day at twenty-eight avoids invalid dates but truncates thirty-day, thirty-one-day, and leap-February destinations.","family":"time-calendar-month-clamp","id":"FA-291","implementations":{"attempt":{"sha256":"682a36f70635b46063f9848be47ca87c42c4323add4b48c5bbf493361fe5c179","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nfrom datetime import date, timedelta\nimport calendar\nN = 1\nobservations = []\ndef solve(text, months):\n    original = date.fromisoformat(text)\n    index = original.year * 12 + original.month - 1 + months\n    year, month = divmod(index, 12)\n    return date(year, month + 1, min(original.day, 28)).isoformat()\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nyear = 2019 + N\nfebruary_day = [29, 28, 28, 28, 29][N - 1]\ncheck('January end clamps to actual February', solve(f'{year}-01-31', 1), f'{year}-02-{february_day}')\ncheck('two-month move clamps only at destination', solve(f'{year}-01-31', 2), f'{year}-03-31')\ncheck('reverse month movement', solve(f'{year}-03-31', -1), f'{year}-02-{february_day}')\ncheck('year rollover with variable offset', solve('2023-12-15', N), f'2024-{N:02d}-15')\ncheck('zero offset preserves month end', solve(f'{year}-07-31', 0), f'{year}-07-31')\ncheck('century divisible by four hundred is leap', solve('2000-01-31', 1), '2000-02-29')\ncheck('other century is not leap', solve('2100-01-31', 1), '2100-02-28')\ncheck('thirty-day destination', solve(f'{year}-03-31', 1), f'{year}-04-30')\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"3cd3b42c0c60d12bd68836afd3dc504bb8b4c32e25515ef099f83fb0161bcf02","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nfrom datetime import date, timedelta\nimport calendar\nN = 1\nobservations = []\ndef solve(text, months):\n    return (date.fromisoformat(text) + timedelta(days=30 * months)).isoformat()\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nyear = 2019 + N\nfebruary_day = [29, 28, 28, 28, 29][N - 1]\ncheck('January end clamps to actual February', solve(f'{year}-01-31', 1), f'{year}-02-{february_day}')\ncheck('two-month move clamps only at destination', solve(f'{year}-01-31', 2), f'{year}-03-31')\ncheck('reverse month movement', solve(f'{year}-03-31', -1), f'{year}-02-{february_day}')\ncheck('year rollover with variable offset', solve('2023-12-15', N), f'2024-{N:02d}-15')\ncheck('zero offset preserves month end', solve(f'{year}-07-31', 0), f'{year}-07-31')\ncheck('century divisible by four hundred is leap', solve('2000-01-31', 1), '2000-02-29')\ncheck('other century is not leap', solve('2100-01-31', 1), '2100-02-28')\ncheck('thirty-day destination', solve(f'{year}-03-31', 1), f'{year}-04-30')\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"fixed":{"sha256":"c8d0f3b82b455305b42700e8223ddcd45d3ab4560c5bdc29b86064ba05c25fb9","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nfrom datetime import date, timedelta\nimport calendar\nN = 1\nobservations = []\ndef solve(text, months):\n    original = date.fromisoformat(text)\n    index = original.year * 12 + original.month - 1 + months\n    year, month = divmod(index, 12)\n    month += 1\n    day = min(original.day, calendar.monthrange(year, month)[1])\n    return date(year, month, day).isoformat()\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nyear = 2019 + N\nfebruary_day = [29, 28, 28, 28, 29][N - 1]\ncheck('January end clamps to actual February', solve(f'{year}-01-31', 1), f'{year}-02-{february_day}')\ncheck('two-month move clamps only at destination', solve(f'{year}-01-31', 2), f'{year}-03-31')\ncheck('reverse month movement', solve(f'{year}-03-31', -1), f'{year}-02-{february_day}')\ncheck('year rollover with variable offset', solve('2023-12-15', N), f'2024-{N:02d}-15')\ncheck('zero offset preserves month end', solve(f'{year}-07-31', 0), f'{year}-07-31')\ncheck('century divisible by four hundred is leap', solve('2000-01-31', 1), '2000-02-29')\ncheck('other century is not leap', solve('2100-01-31', 1), '2100-02-28')\ncheck('thirty-day destination', solve(f'{year}-03-31', 1), f'{year}-04-30')\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":" 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.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"time-calendar-month-clamp","generated_at":"2026-09-29T14:36:52.038828+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Billing dates and calendar schedules need an explicit month-end convention. Calendar movement is not equivalent to adding elapsed days or repeatedly applying a one-month clamp.","repair":"Move the year/month pair by the requested number of months, then clamp the original day to that destination month's actual length.","root_cause":"Calendar month movement is replaced with fixed-duration movement or a universal twenty-eight-day cap.","sha256":"7bd6a63044f8d966259a0dd388753a70888ae4567aa48361313c96947d776962","title":"Adding a calendar month drifts past the target month · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":33.951,"exit_code":1,"observations":[{"actual":"2020-02-28","check":"January end clamps to actual February","expected":"2020-02-29","passed":false},{"actual":"2020-03-28","check":"two-month move clamps only at destination","expected":"2020-03-31","passed":false},{"actual":"2020-02-28","check":"reverse month movement","expected":"2020-02-29","passed":false},{"actual":"2024-01-15","check":"year rollover with variable offset","expected":"2024-01-15","passed":true},{"actual":"2020-07-28","check":"zero offset preserves month end","expected":"2020-07-31","passed":false},{"actual":"2000-02-28","check":"century divisible by four hundred is leap","expected":"2000-02-29","passed":false},{"actual":"2100-02-28","check":"other century is not leap","expected":"2100-02-28","passed":true},{"actual":"2020-04-28","check":"thirty-day destination","expected":"2020-04-30","passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"January end clamps to actual February\", \"actual\": \"2020-02-28\", \"expected\": \"2020-02-29\", \"passed\": false}, {\"check\": \"two-month move clamps only at destination\", \"actual\": \"2020-03-28\", \"expected\": \"2020-03-31\", \"passed\": false}, {\"check\": \"reverse month movement\", \"actual\": \"2020-02-28\", \"expected\": \"2020-02-29\", \"passed\": false}, {\"check\": \"year rollover with variable offset\", \"actual\": \"2024-01-15\", \"expected\": \"2024-01-15\", \"passed\": true}, {\"check\": \"zero offset preserves month end\", \"actual\": \"2020-07-28\", \"expected\": \"2020-07-31\", \"passed\": false}, {\"check\": \"century divisible by four hundred is leap\", \"actual\": \"2000-02-28\", \"expected\": \"2000-02-29\", \"passed\": false}, {\"check\": \"other century is not leap\", \"actual\": \"2100-02-28\", \"expected\": \"2100-02-28\", \"passed\": true}, {\"check\": \"thirty-day destination\", \"actual\": \"2020-04-28\", \"expected\": \"2020-04-30\", \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":36.139,"exit_code":1,"observations":[{"actual":"2020-03-01","check":"January end clamps to actual February","expected":"2020-02-29","passed":false},{"actual":"2020-03-31","check":"two-month move clamps only at destination","expected":"2020-03-31","passed":true},{"actual":"2020-03-01","check":"reverse month movement","expected":"2020-02-29","passed":false},{"actual":"2024-01-14","check":"year rollover with variable offset","expected":"2024-01-15","passed":false},{"actual":"2020-07-31","check":"zero offset preserves month end","expected":"2020-07-31","passed":true},{"actual":"2000-03-01","check":"century divisible by four hundred is leap","expected":"2000-02-29","passed":false},{"actual":"2100-03-02","check":"other century is not leap","expected":"2100-02-28","passed":false},{"actual":"2020-04-30","check":"thirty-day destination","expected":"2020-04-30","passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"January end clamps to actual February\", \"actual\": \"2020-03-01\", \"expected\": \"2020-02-29\", \"passed\": false}, {\"check\": \"two-month move clamps only at destination\", \"actual\": \"2020-03-31\", \"expected\": \"2020-03-31\", \"passed\": true}, {\"check\": \"reverse month movement\", \"actual\": \"2020-03-01\", \"expected\": \"2020-02-29\", \"passed\": false}, {\"check\": \"year rollover with variable offset\", \"actual\": \"2024-01-14\", \"expected\": \"2024-01-15\", \"passed\": false}, {\"check\": \"zero offset preserves month end\", \"actual\": \"2020-07-31\", \"expected\": \"2020-07-31\", \"passed\": true}, {\"check\": \"century divisible by four hundred is leap\", \"actual\": \"2000-03-01\", \"expected\": \"2000-02-29\", \"passed\": false}, {\"check\": \"other century is not leap\", \"actual\": \"2100-03-02\", \"expected\": \"2100-02-28\", \"passed\": false}, {\"check\": \"thirty-day destination\", \"actual\": \"2020-04-30\", \"expected\": \"2020-04-30\", \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":37.372,"exit_code":0,"observations":[{"actual":"2020-02-29","check":"January end clamps to actual February","expected":"2020-02-29","passed":true},{"actual":"2020-03-31","check":"two-month move clamps only at destination","expected":"2020-03-31","passed":true},{"actual":"2020-02-29","check":"reverse month movement","expected":"2020-02-29","passed":true},{"actual":"2024-01-15","check":"year rollover with variable offset","expected":"2024-01-15","passed":true},{"actual":"2020-07-31","check":"zero offset preserves month end","expected":"2020-07-31","passed":true},{"actual":"2000-02-29","check":"century divisible by four hundred is leap","expected":"2000-02-29","passed":true},{"actual":"2100-02-28","check":"other century is not leap","expected":"2100-02-28","passed":true},{"actual":"2020-04-30","check":"thirty-day destination","expected":"2020-04-30","passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"January end clamps to actual February\", \"actual\": \"2020-02-29\", \"expected\": \"2020-02-29\", \"passed\": true}, {\"check\": \"two-month move clamps only at destination\", \"actual\": \"2020-03-31\", \"expected\": \"2020-03-31\", \"passed\": true}, {\"check\": \"reverse month movement\", \"actual\": \"2020-02-29\", \"expected\": \"2020-02-29\", \"passed\": true}, {\"check\": \"year rollover with variable offset\", \"actual\": \"2024-01-15\", \"expected\": \"2024-01-15\", \"passed\": true}, {\"check\": \"zero offset preserves month end\", \"actual\": \"2020-07-31\", \"expected\": \"2020-07-31\", \"passed\": true}, {\"check\": \"century divisible by four hundred is leap\", \"actual\": \"2000-02-29\", \"expected\": \"2000-02-29\", \"passed\": true}, {\"check\": \"other century is not leap\", \"actual\": \"2100-02-28\", \"expected\": \"2100-02-28\", \"passed\": true}, {\"check\": \"thirty-day destination\", \"actual\": \"2020-04-30\", \"expected\": \"2020-04-30\", \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}