date_time.unit.day is a 5-bit bitfield (max 31). Incrementing 31
directly in the bitfield wrapped to 0 via truncation before the
day > days_in_month bounds check ever ran, so the overflow was
never caught. The result decoded as "day 0" of the current month,
i.e. the last day of the previous month, silently rolling the
displayed date backwards (e.g. Aug 31 -> Jul 31 -> Jun 30).
Compute the incremented day in a plain uint8_t local first, compare
it against the month length, and only then write the final value
into the bitfield.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSucp94GA31sshe5AjvSzQ
The local days_in_month table in _increment_date() listed July as
having 30 days instead of 31, diverging from the correct table in
_days_in_month(). This made July 31 unreachable when incrementing
the day field in settings mode.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSucp94GA31sshe5AjvSzQ
The Frq page used remainderf to extract the fractional part of the
correction value, but remainderf rounds to the nearest integer and
returns negative results when the fraction exceeds 0.5. This caused
values like 0.965 ppm to render as " 0-350" instead of " 09650".
Switch to fmodf, matching the DELtA page above.
With double tap enabled, one had to tap not too fast on
the watch to increment the minutes regularly. Otherwise,
some taps would be discarded.
This made using the countdown face without looking at the
screen for acknowledgement of taps impossible.
It was also impossible to increment minutes quickly, every second tap
would be discarded.
Full implementation of the local solar time complication using the
pveducation.org formula set (LSTM, B, EoT, TC, LST, HRA). EoT and TC
are cached by day-of-year and recomputed once at midnight rollover.
Three display modes cycle with the Alarm button:
SO HH:MM:SS — Local Solar Time
nO HH:MM — Solar Noon in local clock time
Hr ±DDD — Hour Angle in degrees
Location is read from location.u32 on the filesystem. In the simulator
the browser lat/lon globals are written to location.u32 on activation
if not already set, fixing the "no Loc" issue in the emulator.