Extend the recurrence lookup tables past 2035 (needs a data source or a new dependency) #114

Open
opened 2026-09-04 16:18:42 +00:00 by claude-bot · 0 comments
Contributor

Split out of #61, which asked to "extend the tables while at it (cheap to add 2036–2045 now)". It turns out not to be cheap, and the reason is worth recording rather than rediscovering.

#61's guard is done: Iris now warns loudly and shows a banner when the loaded years outrun the tables, so this is no longer a silent failure. This issue is the actual extension.

What needs extending

Six tables in backend/app/services/recurrence.py, all covering 2020–2035:

Table Events
HINDU_LUNAR_TABLE Diwali
LUNAR_NEW_YEAR_TABLE Lunar New Year
ASTRONOMICAL_DATES spring equinox, summer solstice, fall equinox, winter solstice

table_horizon() is the minimum across tables, so extending only some of them moves nothing.

Why it can't be done from current dependencies

Checked, not assumed:

  • holidays stops at 2035 itself. holidays.country_holidays("IN", years=[2036]) warns "Requested Holidays are available only from 2001 to 2035" and returns nothing for Diwali. It also yields no Chinese New Year entries for CN. The obvious escape hatch has exactly the same horizon.
  • astral has no solstice or equinox function. It computes sunrise, sunset, dawn, dusk, golden hour and sun_declination, but nothing that gives an equinox instant directly.

So this needs either curated data from an authority, or a new dependency.

Routes, easiest first

Solstices and equinoxes are the tractable ones — purely astronomical, no cultural calendar. Either add an ephemeris library (skyfield, ephem) or implement Meeus's equinox/solstice algorithm, which is well documented and self-contained.

Lunar New Year needs a Chinese-calendar library (lunardate, borax) or tabulated data. It is the second new moon after the winter solstice, so an ephemeris gets most of the way, but the rule is defined against China Standard Time and the edge cases matter.

Diwali is the hardest. It is tithi-based (Amavasya of Kartika), not a simple lunar phase, and needs a panchanga source. Regional variation exists. This is the one most likely to want curated data rather than computation.

Validate before trusting

Whatever route: run it against the existing 2020–2035 entries first. Sixteen known-good years per table is a real test. A computation that reproduces all of them can be trusted going forward; one that disagrees anywhere should not be used until the disagreement is understood.

Deliberately not attempted by hand in #61 — sixty guessed astronomical dates would be silently wrong in a way that is much harder to notice than the events simply being absent, which is what the guard now reports.

Acceptance criteria

  • All six tables cover at least 2045, or the values are computed at runtime
  • Whatever produces the dates reproduces the existing 2020–2035 values exactly, with a test asserting it
  • table_horizon() reflects the new coverage (it is derived, so this should follow automatically)
  • docs/troubleshooting.md "Recurrence horizon" updated to describe whatever the new mechanism is

Split from #61.

Split out of #61, which asked to *"extend the tables while at it (cheap to add 2036–2045 now)"*. It turns out not to be cheap, and the reason is worth recording rather than rediscovering. #61's guard is done: Iris now warns loudly and shows a banner when the loaded years outrun the tables, so this is no longer a *silent* failure. This issue is the actual extension. ## What needs extending Six tables in `backend/app/services/recurrence.py`, all covering **2020–2035**: | Table | Events | |---|---| | `HINDU_LUNAR_TABLE` | Diwali | | `LUNAR_NEW_YEAR_TABLE` | Lunar New Year | | `ASTRONOMICAL_DATES` | spring equinox, summer solstice, fall equinox, winter solstice | `table_horizon()` is the **minimum** across tables, so extending only some of them moves nothing. ## Why it can't be done from current dependencies Checked, not assumed: - **`holidays` stops at 2035 itself.** `holidays.country_holidays("IN", years=[2036])` warns *"Requested Holidays are available only from 2001 to 2035"* and returns nothing for Diwali. It also yields no Chinese New Year entries for `CN`. The obvious escape hatch has exactly the same horizon. - **`astral` has no solstice or equinox function.** It computes sunrise, sunset, dawn, dusk, golden hour and `sun_declination`, but nothing that gives an equinox instant directly. So this needs either curated data from an authority, or a new dependency. ## Routes, easiest first **Solstices and equinoxes** are the tractable ones — purely astronomical, no cultural calendar. Either add an ephemeris library (`skyfield`, `ephem`) or implement Meeus's equinox/solstice algorithm, which is well documented and self-contained. **Lunar New Year** needs a Chinese-calendar library (`lunardate`, `borax`) or tabulated data. It is the second new moon after the winter solstice, so an ephemeris gets most of the way, but the rule is defined against China Standard Time and the edge cases matter. **Diwali is the hardest.** It is tithi-based (Amavasya of Kartika), not a simple lunar phase, and needs a panchanga source. Regional variation exists. This is the one most likely to want curated data rather than computation. ## Validate before trusting Whatever route: **run it against the existing 2020–2035 entries first.** Sixteen known-good years per table is a real test. A computation that reproduces all of them can be trusted going forward; one that disagrees anywhere should not be used until the disagreement is understood. Deliberately not attempted by hand in #61 — sixty guessed astronomical dates would be silently wrong in a way that is much harder to notice than the events simply being absent, which is what the guard now reports. ## Acceptance criteria - [ ] All six tables cover at least 2045, or the values are computed at runtime - [ ] Whatever produces the dates reproduces the existing 2020–2035 values exactly, with a test asserting it - [ ] `table_horizon()` reflects the new coverage (it is derived, so this should follow automatically) - [ ] `docs/troubleshooting.md` "Recurrence horizon" updated to describe whatever the new mechanism is Split from #61.
claude-bot added this to the v1.2.0 milestone 2026-09-04 16:18:52 +00:00
Sign in to join this conversation.
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
rbrooks/Iris-WLED#114
No description provided.