The twilight grazing residual is gone, and the bug behind it turned out not to be an accuracy problem at all. Moon rise and set now say what they mean at high latitude.
| Header | Version | Changed |
|---|---|---|
prayertimes.h |
v0.2.2 to v0.2.3 |
yes |
hijri.h |
v0.1.0 to v0.1.1 |
yes |
timezone.h |
v0.1.1 |
no |
prayertimes.h v0.2.3
refine_event is gone (#85, closing #79). Fajr, isha, sunrise and sunset are now solved the same way, by bisecting true solar altitude between local noon and local midnight, so the event's existence is decided at the event rather than at 0h UT.
#79 asked for a closest approach method, on the reading that the residual was the solver failing to converge on a real crossing. It was not. Of the 186 grazing points the oracle flagged, 45 were days on which the Sun never reaches the angle at all, so the 30 arcmin being measured was the distance to an event that was not there. Deciding existence first removes the residual without needing a closest approach method.
| Oracle | Before | After |
|---|---|---|
| twilight grazing points | 186, max 30.1964 arcmin | 160, max 0.1970 arcmin |
| polar grazing points | 172, max 9.3160 arcmin | 169, max 0.4556 arcmin |
Measured against the 2026.08.21 asset over MWL at longitude 0, latitude -70 to 70 in steps of 5, every day of 2026, all five fields. Of 52925 values, 30968 move. 14 change the displayed HH:MM, and every one of those 14 is a day on which no event exists and the library now says so instead of reporting a near midnight crossing that was wrong by up to four hours. The other 30954 move by at most 0.0003 seconds.
Existence itself was then checked directly against JPL DE440 over the same grid, 42340 decisions across sunrise, sunset, fajr and isha. Two disagree, both a single day at latitude -70 in November, where the low precision solar model and DE440 differ by 0.0035 degrees on a 0.0013 degree margin. That is the sun model's own noise, not the solver's.
No API change. struct PrayerTimes, MethodParams and every function signature are identical to v0.2.2.
hijri.h v0.1.1
Both rise and set finders classified a failed search from one extra sample, treating it as the extremum of the search window (#83, closing #82). That holds for the Sun, whose finder is handed local midnight so the sample lands on local noon. It does not hold for the Moon, whose own day is 24h 50m, so the sample lands at an arbitrary phase.
Latitude -89 to 89 in steps of 2, every day of 2026:
| before | after | |
|---|---|---|
| false moonset labels | 820 | 0 |
| false sunset labels | 26 | 0 |
| events the finder missed | 12 | 0 |
Not near misses. NEVER_RISES for a Moon spanning -15.38 to +3.60 degrees.
HIJRI_EVENT_NOT_FOUND is no longer reserved. A 24 hour window holding no moonset is not always circumpolar, since the Moon sets once per 24h 50m, so roughly one evening in thirty has no moonset at any latitude. Callers that switch exhaustively on HijriEventStatus should check that arm before upgrading.
Documentation
hijri.h now carries a measured statement of the range it is good over geographically, not a described one (#84, second half of #27). Latitude verdicts with the errors that justify them, why the equatorial 3.4 percent figure is not what it looks like, the longitude table, and where the elevation reasoning lives.
Known issues
#51 and #56 remain open design questions, on polar circle behaviour and on whether prayer times should carry a day offset outside 0 to 24.
The bracket between local noon and local midnight uses noon plus 12 hours for midnight, which is the antisolar transit to within the equation of time. The approximation is marked in the source with the measurement that bounds it.