feat: add Computus for Gregorian Easter (Meeus/Jones/Butcher) #206

Merged
manlycucumber merged 1 commit from feature/15-computus into develop 2026-07-01 05:41:34 +00:00
manlycucumber commented 2026-07-01 05:41:03 +00:00 (Migrated from github.com)

Closes #15. Opens Epic #14 (Temporal cycle / Factory) — the keystone the whole temporal phase anchors to.

What lands

  • Introibo\Core\Temporal\ComputusgregorianEaster(int $year): DateTimeImmutable, a clean-room implementation of the anonymous Gregorian algorithm (Meeus / Jones / Butcher). Pure integer arithmetic, no external dependency, no reliance on the platform's easter_days() (the validation epic cross-checks the two).
  • Returns a UTC-midnight date — a liturgical day is a calendar date carried with a fixed time and zone so downstream date maths is DST-free.
  • Years before 1583 (the first Gregorian Easter) are rejected; the pre-reform Julian computus is a later, additive concern.

Verification

  • 15 known Easter dates across the centuries (1583, 1818, 1911, 1943, 1954, 1955, 1962, 2000, 2008, 2011, 2024–2027, 2038), including both extremes: earliest possible 22 March (1818) and latest possible 25 April (1943, 2038).
  • Invariant sweep 1583–2299: every Easter is a Sunday and falls within the 22 Mar – 25 Apr window (3.8k assertions).

Acceptance criteria

  • Returns the Gregorian Easter date for any year via Meeus/Jones/Butcher
  • Implementation is pure with no external dependency
  • Unit tests cover a spread of known Easter dates across centuries
  • Edge years (earliest 22 Mar, latest 25 Apr) are asserted

Local: composer lint clean · composer analyse PHPStan L6 [OK] · composer test 107/107 green.

Closes #15. Opens Epic #14 (Temporal cycle / Factory) — the keystone the whole temporal phase anchors to. ## What lands - **`Introibo\Core\Temporal\Computus`** — `gregorianEaster(int $year): DateTimeImmutable`, a **clean-room** implementation of the anonymous Gregorian algorithm (Meeus / Jones / Butcher). Pure integer arithmetic, no external dependency, no reliance on the platform's `easter_days()` (the validation epic cross-checks the two). - Returns a **UTC-midnight** date — a liturgical day is a calendar date carried with a fixed time and zone so downstream date maths is DST-free. - Years before **1583** (the first Gregorian Easter) are rejected; the pre-reform Julian computus is a later, additive concern. ## Verification - **15 known Easter dates** across the centuries (1583, 1818, 1911, 1943, 1954, 1955, 1962, 2000, 2008, 2011, 2024–2027, 2038), including both extremes: earliest possible **22 March** (1818) and latest possible **25 April** (1943, 2038). - **Invariant sweep 1583–2299**: every Easter is a Sunday and falls within the 22 Mar – 25 Apr window (3.8k assertions). ## Acceptance criteria - [x] Returns the Gregorian Easter date for any year via Meeus/Jones/Butcher - [x] Implementation is pure with no external dependency - [x] Unit tests cover a spread of known Easter dates across centuries - [x] Edge years (earliest 22 Mar, latest 25 Apr) are asserted Local: `composer lint` clean · `composer analyse` PHPStan L6 `[OK]` · `composer test` 107/107 green.
Sign in to join this conversation.
No reviewers
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
Directorium/Core!206
No description provided.