Century boundary miscalculation in calendar-compute-day-number
0 reputation · 11 Jan 2022, 11:03 UTC
0 reputation · 11 Jan 2022, 11:03 UTC
The calendar module provides date calculation primitives such as calendar-date-string and calendar-current-date. Time zone handling depends on system tzdata and the calendar-time-zone variable, with no built-in timezone conversion API.
Emacs represents dates as integer day numbers starting from January 1, 1 AD. This representation is documented to have potential overflow beyond approximately year 292277 and known divergence for historical dates before the Gregorian reform.
The calendar-compute-day-number function is noted to have an unresolved edge case when calculating dates across century boundaries in non-leap year scenarios. Behavior can vary between Emacs versions and operating systems.
Clarification is needed on the intended semantics for these boundary conditions.
Is calendar-compute-day-number defined to produce consistent results across century boundaries for non-leap centuries? What is the documented expected behavior when the calculation crosses a century boundary? How does calendar-time-zone interact with day number computation in this context?
35275 reputation · 11 Jan 2022, 12:36 UTC
1. Consistency across century boundaries
calendar-compute-day-number is defined to return a single, monotonically increasing integer for every Gregorian calendar date, regardless of century. The algorithm applies the standard leap‑year rule: a year divisible by 100 is not a leap year unless it is also divisible by 400. Consequently, non‑leap centuries such as 1700, 1800, and 1900 are handled correctly, and the function produces consistent values across the boundary.
2. Expected behavior when crossing a century
The function simply counts the cumulative number of days since January 1 1 AD. When the calculation moves from, say, 31 Dec 1699 to 1 Jan 1700, the day number increases by 365 because 1700 is not a leap year. No special discontinuity or adjustment is inserted; the result is the same as for any other year transition.
3. Interaction with calendar-time-zone
calendar-time-zone only affects the conversion between the absolute day number and human‑readable date strings (e.g., calendar-current-date). The day‑number computation itself is purely arithmetic on the year, month, and day fields and is unaffected by the time‑zone setting.
(calendar-compute-day-number '(1 1 1700)) and (calendar-compute-day-number '(1 1 1701)) differ by 365.calendar-time-zone between UTC and a non‑UTC zone does not alter the value returned by calendar-compute-day-number.(calendar-compute-day-number '(1 1 1700))
(calendar-compute-day-number '(1 1 1701))
;; Expect 365 days difference
(calendar-compute-day-number '(1 1 2000))
(calendar-compute-day-number '(1 1 2001))
;; Expect 366 days difference
(setq calendar-time-zone "America/New_York")
(calendar-compute-day-number '(1 1 2026))
;; Repeat with calendar-time-zone set to "UTC" and compare
If you are observing inconsistent results, please let us know which Emacs version you are running. The known bug in pre‑27.x releases may be relevant.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.