How to Use This Tool
Pick an integer width, a tick rate and an epoch. The countdown is to the moment the counter can no longer represent the current time.
What actually happens in 2038
A signed 32-bit integer reaches 2,147,483,647. Counting seconds from 1970, that is 2038-01-19T03:14:07Z. Add one second and the bit pattern becomes −2,147,483,648, which reads as 1901-12-13T20:45:52Z.
The important part is that nothing fails. No exception is raised, no value is out of range, and the result is a perfectly well-formed date. Every check that only asks "did this parse" passes.
Downstream, a certificate looks expired, an account looks 137 years old, a scheduled job looks overdue, and an interval calculation goes hugely negative. Tracing any of those back to an integer width is slow work.
It is not a 2038 problem, it is a today problem
Systems fail when they first compute a date beyond the limit, not when the limit arrives.
- A 30-year mortgage signed today matures in 2056.
- A 20-year certificate or long-lived key already crosses it.
- Anything with a far-future "not before" or "never expires" placeholder does the same.
Those calculations are happening now, which is why the useful question is not how many years remain but how far ahead your software looks.
The rollover nobody plans for
Signed 32-bit milliseconds reach their limit after 2,147,483,647 milliseconds — 24.9 days. Unsigned, it is 49.7 days.
This is the classic embedded and long-uptime bug. A device works perfectly in testing, runs for a month, and then does something inexplicable involving a negative elapsed time. Rebooting fixes it, which makes it very hard to reproduce and very easy to dismiss.
The safe pattern is to compare elapsed times as (now − then) in unsigned arithmetic
rather than testing now > deadline, because the subtraction stays correct across a single
wrap and the comparison does not.
What 64 bits buys
- Signed 64-bit seconds — roughly 292 billion years. Not a problem anyone needs to think about again.
- Signed 64-bit nanoseconds — 2262-04-11. Finite, and used by several languages and databases for high-resolution timestamps. Two hundred years is comfortable and it is not forever.
- JavaScript numbers hold integers exactly to 253, so millisecond timestamps are safe for about 285,000 years while microsecond ones are not.
What to actually do
Fixing this is rarely about the language and almost always about storage and interfaces:
- Database columns. A 32-bit integer timestamp column is the usual culprit, and changing it means a migration rather than a recompile.
- Wire formats and file formats. Anything with a fixed layout has the width baked in, and both ends have to agree before it changes.
- Embedded devices that cannot be updated at all, which is the part of the problem that does not get solved by anyone deciding to solve it.
Testing is straightforward and rarely done: set a system clock to 2038-01-19 and run the suite.
