~ / topics / Related Bugs
$man year-2106-and-beyond

Year 2106 and Beyond

In brief: Every way of storing time has a last date it can represent. Treating Unix's 32-bit seconds counter as unsigned instead of signed moves the 2038 limit to 7 February 2106. Some systems do this as a 2038 workaround, but it only postpones the problem. Moving to a signed 64-bit counter pushes the limit about 292 billion years ahead, far longer than the Sun will last. In between are other fixed limits: old Mac disks (2040), IBM mainframe clocks (2042), DOS/FAT file dates (2107), ext4 (2446), and four-digit-year software (9999, the "Y10K" problem).

Risk level Low to Medium (Medium for 2040–2042 and for 32-bit-unsigned "fixes" in long-lived data)
Status The 64-bit time_t migration removes the practical limit. Format- and hardware-specific limits remain
Last reviewed 2026-10-21

Overview

Two decisions determine when a time counter runs out: how many bits it has, and whether it is signed. A signed 32-bit seconds counter starting in 1970 runs out on 2038-01-19 03:14:07 UTC (see Year-2038-Problem). Treating the same 32 bits as unsigned doubles the forward range but gives up every date before 1970:

Representation (seconds since 1970-01-01 UTC) Last representable instant Gives up
Signed 32-bit 2038-01-19 03:14:07 —
Unsigned 32-bit 2106-02-07 06:28:15 All dates before 1970
Signed 64-bit About 292,277,026,596 CE Nothing practical

(The 2106 and 64-bit figures are arithmetic: 1970 + (2³² − 1) s, and 1970 + (2⁶³ − 1) s ≈ 292,277,024,627 Gregorian years. They match the 2106 value given in Year-2038-Problem.)

The NTPsec documentation states that 64-bit systems "are not affected for roughly 292 billion years" [1].

Is "unsigned 32-bit" a valid 2038 fix?

As a stopgap for protocols and on-disk formats that cannot be widened, yes. Several systems do it (see Year-2038-Problem for the documented cases). The costs are:

Technical details

Far-future limits

Date (UTC unless noted) Limit Cause Ref
2036-02-07 06:28:16 NTP era 0 → 1 Unsigned 32-bit seconds since 1900. See NTP-Era-2036 [2]
2038-01-19 03:14:07 Unix time_t Signed 32-bit seconds since 1970. See Year-2038-Problem —
2038-11-20/21 GPS LNAV week rollover 10-bit week number. See GPS-Week-Rollover [3]
2040-02-06 06:28:15 GMT HFS+ (Mac OS Extended) "Unsigned 32-bit integers ... containing the number of seconds since midnight, January 1, 1904, GMT. ... The maximum representable date is February 6, 2040 at 06:28:15 GMT" [4]
2042-09-17 IBM System/370 → z/Architecture 64-bit TOD clock 64-bit time-of-day clock with epoch 1900-01-01. IBM: "will wrap on September 17, 2042 at 23:59:57 TAI." The extended 128-bit TOD (STCKE) adds an epoch byte and has "no issue with roll over in 2042" [5]
2100-02-28 → 03-01 Century non-leap year Code that treats every year divisible by 4 as a leap year gets 2000 right but 2100 wrong. 2100 is not a leap year [6]
2106-02-07 06:28:15 Unsigned 32-bit Unix seconds See above arithmetic
2107-12-31 MS-DOS / FAT date 7-bit year offset from 1980 (bits 9–15). The format can represent only "dates between 1/1/1980 and 12/31/2107" [7]
2137 (early Jan) GPS CNAV 13-bit week 8,192-week cycle [3]
2446-05-10 ext4 extended timestamps Two extra "epoch" bits extend 32-bit seconds, "deferring the year 2038 problem to the year 2446" [8]
9999-12-31 23:59:59.9999999 Y10K: four-digit-year software e.g. .NET DateTime.MaxValue [9]
30827-12-31 (30828) Windows SYSTEMTIME / FILETIME wYear valid range 1601–30827. The maximum FILETIME converts to a date in 30828 that cannot be converted back [10][11]
+275760-09-13 JavaScript Date Time values limited to ±8.64 × 10¹⁵ ms (100,000,000 days) from 1970 (year by arithmetic) [12]
+1,000,000,000-12-31 Java Instant.MAX "The maximum supported Instant, '1000000000-12-31T23:59:59.999999999Z'" [13]
~292,277,026,596 CE Signed 64-bit seconds since 1970 2⁶³ − 1 seconds [1]
~584 billion-year span NTP 128-bit date format 64-bit signed seconds field [2]

Classic Mac and HFS+ (2040)

Classic Mac OS and HFS+ count seconds from 1904-01-01. HFS+ stores them as unsigned 32-bit values in GMT, while the original HFS stored local time [4]. TN1150 also notes that the volume header's creation date is stored in local time, not GMT [4]. Linux kernel and Darwin implementations have at times handled values outside 1970–2038 differently from Apple's documented 1904–2040 range (per a 2018 Linux kernel discussion) [16]. See File-Systems and OS-macOS-and-iOS.

IBM TOD clock (2042)

The S/370-lineage TOD clock is a 64-bit binary counter with its epoch at 1900-01-01 00:00 UTC [5]. Bit 51 represents one microsecond (per the architecture manual as quoted on a 2000 linux-kernel mailing-list post. Not checked against the current Principles of Operation) [15]. The 64-bit value wraps in September 2042 [5]. Pure arithmetic (2⁵² µs after 1900-01-01) gives 2042-09-17 23:53:47 without leap seconds. IBM's own slide gives 23:59:57 TAI [5], so use the vendor figure for planning. IBM notes that the wrap is already causing errors in calculations that look 20 years ahead, and that after the wrap tpf_STCK_to_time() would return "a negative number that represents a time in the year 1900" [5]. The fix is the 16-byte extended TOD format (STCKE) [5].

Y10K

RFC 2550, "Y10K and Beyond" (1 April 1999), is an April Fools' RFC by Glassman, Manasse and Mogul that proposed a variable-length year format. Its joke rests on a real point: four-digit years run out after 9999 [14]. In practice, many date types cap at 9999-12-31, including .NET's DateTime [9]. This is mainly a problem for sentinel values. Programs that use 9999-12-31 as "never expires" will break if they add even one day to it.

DateTime.MaxValue.AddDays(1);   // throws ArgumentOutOfRangeException

Affected versions / products

Area Watch for
Kernel / libc using unsigned 32-bit time as a bridge Pre-1970 data loss. 2106
HFS+ volumes, archives and disk images 2040
IBM Z / z/TPF code using the 8-byte TOD and time_t conversions 2042, and look-ahead failures before then [5]
FAT, ZIP and other DOS-timestamp formats 1980 lower bound, 2107 upper bound [7]
Databases and apps using 9999-12-31 sentinels Overflow on date arithmetic

Risk & compliance notes

Detection & mitigation

See Testing-and-Detection and Remediation-Guide.

See also

References

  1. Rollover issues — NTPsec documentation. 64-bit systems unaffected for about 292 billion years. 2038 wrap to 1901.
  2. RFC 5905: NTPv4 Specification — IETF, June 2010. Era 1 in 2036 and the 584-billion-year date format.
  3. GPS Week Number Rollover — GPS.gov (archive). LNAV rollover in 2038 and CNAV in 2137.
  4. Technical Note TN1150: HFS Plus Volume Format — Apple Developer (archive). HFS+ dates and the 2040 maximum.
  5. z/TPF time_t Enhancement — IBM, TPF Users Group, Apr 2023. TOD wrap on 17 Sep 2042, look-ahead errors and STCKE.
  6. Method to determine whether a year is a leap year — Microsoft Learn. 2100 is not a leap year.
  7. FileTimeToDosDateTime function — Microsoft Learn. DOS date range 1980–2107. DosDateTimeToFileTime bit layout.
  8. Re: [PATCH v4 1/2] ext4: Fix handling of extended tv_sec — LKML, Nov 2013. Extra epoch bits extend ext4 to 2446.
  9. DateTime.MaxValue Field — Microsoft Learn. 9999-12-31 23:59:59.9999999.
  10. SYSTEMTIME structure — Microsoft Learn. wYear 1601–30827.
  11. The Old New Thing — Raymond Chen, Microsoft DevBlogs, 21 Sep 2026. Maximum FILETIME converts to year 30828 (seen in search).
  12. ECMAScript Language Specification — Dates and Temporal (TC39 draft). ±8.64 × 10¹⁵ ms time-value range.
  13. java.time.Instant — Android Developers (JDK Javadoc mirror). Instant.MAX.
  14. RFC 2550: Y10K and Beyond — Glassman, Manasse, Mogul, IETF, 1 Apr 1999. April Fools' RFC on Y10K.
  15. Re: time_t size: The year 2038 bug? — linux-kernel mailing list, Jan 2000. Quotes the S/390 TOD bit-51 microsecond increment and the extended-TOD carry byte (seen in search).
  16. [PATCH 1/2] [v2] hfs/hfsplus: follow MacOS time behavior — LKML, Jul 2018. Implementation ranges (1904–2040 vs 1970–2038) for HFS/HFS+ timestamps (seen in search).