| (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](https://en.wikipedia.org/wiki/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](https://en.wikipedia.org/wiki/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: | |
| * [Very Fast 64-bit Date Algorithm](https://www.benjoffe.com/fast-date-64) | |
| * [Inverse Date Algorithm](https://www.benjoffe.com/fast-date#inverse) | |
| * [Fast Leap-Year Check](https://www.benjoffe.com/fast-leap-year#drepper-neri-schneider) | |
| 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. |