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