Files
llvm-tms34010/libc/docs/dev/date_and_time.md
T
Jeff BaileyandRaman Tenneti 2705f4613a [libc] Implement fast date conversion algorithm of Ben Joffe (#208312)
Replaced the loop-based year/month/day extraction in update_from_seconds
with Ben Joffe's "Very Fast 64-bit" date algorithm using multiply-shift
division (4 multiplications, 0 hardware divisions). Also replaced the
mktime inverse with Ben Joffe's inverse date algorithm.

Updated is_leap_year to use the Drepper-Neri-Schneider algorithm (% 25
instead of % 100). Replaced the O(n) yday month-length loop with a
constant-time cumulative-days table lookup.

Uses UInt128 for portable 128-bit support across 64-bit (native) and
32-bit (software fallback) targets.

Raman's benchmarks on x86-64 show a ~13% wall-time improvement:

  Before: real 2.215s, user 2.214s
  After:  real 1.919s, user 1.913s

Algorithm references:
  https://www.benjoffe.com/fast-date-64
  https://www.benjoffe.com/fast-date#inverse
  https://www.benjoffe.com/fast-leap-year#drepper-neri-schneider

---------

Co-authored-by: Raman Tenneti <rtenneti@google.com>
2026-07-10 21:04:22 +01:00

2.3 KiB
Raw Blame History

(date_and_time)=

Date and Time

LLVM-libc implements the C and POSIX date and time functions (gmtime, mktime, etc.) using high-performance algorithms and a 64-bit time_t. This page documents the design decisions and limitations of the implementation.

Calendar Model

LLVM-libc uses the proleptic Gregorian calendar: the modern Gregorian leap-year rules (divisible by 4, except centuries, except quad-centuries) are extended to all dates, including those before the calendar's adoption on October 15, 1582.

This is the model required by the C and POSIX standards. It means that dates before 1582 do not correspond to historical Julian calendar dates. For example, gmtime will report February 29 for the year 400 CE, even though that date was reckoned differently under the Julian calendar in use at the time.

Leap Seconds

POSIX §4.16 defines each day as exactly 86 400 seconds. LLVM-libc follows this convention: leap seconds are not represented and time_t values map to UTC times that ignore leap-second insertions.

64-bit time_t

LLVM-libc requires a 64-bit time_t. A 32-bit time_t is not supported. This avoids the Year 2038 problem and provides a valid range of approximately ±2 billion years from the Unix epoch (January 1, 1970).

Algorithms

The date conversion functions use Ben Joffe's "Very Fast 64-bit" date algorithm, which replaces the traditional loop-based year/month/day extraction with multiply-shift division (four multiplications, zero hardware divisions). The inverse (mktime) path uses the companion inverse algorithm from the same article series. Leap-year testing uses the Drepper–Neri–Schneider algorithm (modulo 25 instead of modulo 100).

These algorithms are described in:

128-bit intermediate arithmetic is used for the multiply-shift steps. On 64-bit targets this maps to the native __uint128_t; on 32-bit targets LLVM-libc's software UInt<128> implementation is used, preserving correctness at a modest performance cost.