feat: add PaschalSkeleton for Easter-anchored movable feasts #207

Merged
manlycucumber merged 1 commit from feature/16-movable-skeleton into develop 2026-07-01 06:26:25 +00:00
manlycucumber commented 2026-07-01 06:25:30 +00:00 (Migrated from github.com)

Closes #16. Continues Epic #14 (Temporal cycle / Factory).

Derives the paschal skeleton — every movable point of the temporal cycle anchored to Easter — from Computus (#15).

What lands

  • Introibo\Core\Temporal\PaschalSkeletonforYear(int) / fromEaster(DateTimeImmutable). Each anchor is a signed day-offset from Easter Sunday (a private const OFFSETS table: Septuagesima −63 … Ash Wednesday −46 … Easter 0 … Ascension +39 … Pentecost +49 … Corpus Christi +60 … Sacred Heart +68). Nothing is hard-coded to a civil date, so leap years are handled for free — Ash Wednesday is always exactly 46 days before Easter.
  • API: date(anchor), all(), static offsets(), and named accessors (septuagesima(), ashWednesday(), ascension(), pentecost(), corpusChristi()).
  • The Major Rogation (25 April) is a fixed civil date, not Easter-relative, so it's deliberately absent.

Verification

  • Marquee anchors across three sample years — including leap-year 2024 whose pre-Lent anchors cross 29 Feb (Ash Wednesday 2024-02-14, Septuagesima 2024-01-28).
  • Independent weekday invariants (Ash Wednesday is a Wednesday, Ascension/Corpus Christi Thursdays, the Sundays are Sundays) — catches off-by-one that same-table arithmetic would hide.
  • Constant day-counts from Easter across leap and common years.

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

Closes #16. Continues Epic #14 (Temporal cycle / Factory). Derives the **paschal skeleton** — every movable point of the temporal cycle anchored to Easter — from `Computus` (#15). ## What lands - **`Introibo\Core\Temporal\PaschalSkeleton`** — `forYear(int)` / `fromEaster(DateTimeImmutable)`. Each anchor is a **signed day-offset from Easter Sunday** (a `private const OFFSETS` table: Septuagesima −63 … Ash Wednesday −46 … Easter 0 … Ascension +39 … Pentecost +49 … Corpus Christi +60 … Sacred Heart +68). Nothing is hard-coded to a civil date, so **leap years are handled for free** — Ash Wednesday is always exactly 46 days before Easter. - API: `date(anchor)`, `all()`, static `offsets()`, and named accessors (`septuagesima()`, `ashWednesday()`, `ascension()`, `pentecost()`, `corpusChristi()`). - The **Major Rogation (25 April)** is a fixed civil date, not Easter-relative, so it's deliberately absent. ## Verification - Marquee anchors across three sample years — including **leap-year 2024** whose pre-Lent anchors cross 29 Feb (Ash Wednesday 2024-02-14, Septuagesima 2024-01-28). - Independent **weekday invariants** (Ash Wednesday is a Wednesday, Ascension/Corpus Christi Thursdays, the Sundays are Sundays) — catches off-by-one that same-table arithmetic would hide. - **Constant day-counts** from Easter across leap and common years. Local: `composer lint` clean · `composer analyse` PHPStan L6 `[OK]` · `composer test` 150/150 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!207
No description provided.