2038 Bug

The year 2038 problem


The Linux 5.10 will include fixes for the Year 2038 problem, aka Y2K38.
The flaw means that many systems can’t conceive of dates beyond 03:14:07 UTC on 19 January 2038.

Y2K was caused by systems representing years with two digits and assuming that a year ending with two zeroes would be 1900. Y2K38 is different because it’s derived from Unix and Unix-like systems counting time since January 1st, 1970 in seconds. Come January 19th, 2038, that number will be a bigger value than can be stored as a single 32-bit integer. At which point, things could get interesting.

The need to remedy the Y2K38 problem has been known before the Y2K problem erupted into the public imagination, proved the world’s most expensive and unspectacular piece of proactive maintenance and inevitably spawned truthers who suggest the whole thing was a hoax dreamed up to make work for the computing services industry.

But perhaps because 2038 is still rather far off, little has been done and that worries the likes of long-time Linux kernel chronicler Jon Corbet.

In every computer systems there is a latent bug that is similar to the so-called ‘Millennium Bug’ or ‘Y2K’ bug or Year 2000 bug, its name is ‘The year 2038 problem’ or ‘Y2K38’. Do not be misled by its definition that makes it seem like a minor problem, the year 2038 bug is a problem that involves a time-wrap problem not handled by programmers and although many overlook it because it is considered remote in time (15 years away from the date of writing) or because it is believed that it will resolves itself with the progressive adoption of 64bit systems, may cause some computer software to fail at some point near the year 2038. Although this may be true for desktop systems frequently updated, it is not so for embedded systems, which have a considerably longer life cycle. Do not forget that the embedded systems are also a lot more critical as they could be used to control devices that can compromise the security or worse the safety of persons.

The more frequent answer to this issue you can find after a long seach on the internet sound like there is nothing to worry about because with over 25 years to spare people are confident that any issues will be resolved before the doomsday scenario has a chance to play out.

What makes January 19, 2038 a special day? Unix and Unix-like operating systems do not calculate time in the Gregorian calendar, they simply count time in seconds since their arbitrary “birthday”, GMT 00:00:00, Thursday, January 1, 1970.

Because the end bit indicating positive/negative integer may flip over, some systems may revert the date to 20:45:52, Friday, December 13, 1901 (which corresponds to GMT 00:00:00 Thursday, January 1, 1970 minus 2**31 seconds). Hence the media may nickname this the “Friday the Thirteenth Bug”.

The problem affects all software and systems that both store system time as a signed 32-bit integer, and interpret this number as the number of seconds since 00:00:00 UTC on Thursday, 1 January 1970. Modern computers use a standard 4 byte integer for this second count. This is 31 bits, storing a maximum value of 231. The remaining bit is the sign. This means that when the second count reaches 2147483647, it will wrap to -2147483648.  In other words, the furthest time that can be represented this way is 03:14:07 UTC on Tuesday, 19 January 2038. Times beyond this moment will “wrap around” and be stored internally as a negative number, which these systems will interpret as a date in 1901 rather than 2038. This is caused by integer overflow.

A quick check with the following Perl script may help determine if your computers will have problems (this requires Perl to be installed on your system, of course):

# I've seen a few versions of this algorithm
# online, I don't know who to credit. I assume
# this code to be GPL unless proven otherwise.
# Comments provided by William Porquet, February 2004.
# You may need to change the line above to 
# reflect the location of your Perl binary
# (e.g. "#!/usr/local/bin/perl").
# Also change this file's name to 'test2038.pl'.
# Don't forget to make this file +x with "chmod".
# On Linux, you can run this from a command line like this:
# ./test2038.pl
use POSIX;
# Use POSIX (Portable Operating System Interface),
# a set of standard operating system interfaces.
$ENV{'TZ'} = "GMT";
# Set the Time Zone to GMT (Greenwich Mean Time) for date calculations.
for ($clock = 2147483641; $clock < 2147483651; $clock++)
    print ctime($clock);
# Count up in seconds of Epoch time just before and after the critical event.
# Print out the corresponding date in Gregorian calendar for each result.
# Are the date and time outputs correct after the critical event second?

For example, the output of this script on Ubuntu 12.04 LTS (Precise) i686 GNU/Linux (kernel 3.5.0-18):

# ./test2038.pl
Tue Jan 19 03:14:01 2038
Tue Jan 19 03:14:02 2038
Tue Jan 19 03:14:03 2038
Tue Jan 19 03:14:04 2038
Tue Jan 19 03:14:05 2038
Tue Jan 19 03:14:06 2038
Tue Jan 19 03:14:07 2038
Fri Dec 13 20:45:52 1901
Fri Dec 13 20:45:52 1901
Fri Dec 13 20:45:52 1901

Windows 2000 Professional with ActivePerl fails in such a manner that it stops displaying the date after the critical second:

C:\>perl test2038.pl
Mon Jan 18 22:14:01 2038
Mon Jan 18 22:14:02 2038
Mon Jan 18 22:14:03 2038
Mon Jan 18 22:14:04 2038
Mon Jan 18 22:14:05 2038
Mon Jan 18 22:14:06 2038
Mon Jan 18 22:14:07 2038

So far, the few operating systems that I haven’t found susceptible to the 2038 bug include very new versions of Unix and Linux ported to 64-bit platforms.

Another example, the output of this script on Ubuntu 10.04 LTS (Lucid) x86_64 GNU/Linux (kernel 2.6.32-50):

# ./test2038.pl
Tue Jan 19 03:14:01 2038
Tue Jan 19 03:14:02 2038
Tue Jan 19 03:14:03 2038
Tue Jan 19 03:14:04 2038
Tue Jan 19 03:14:05 2038
Tue Jan 19 03:14:06 2038
Tue Jan 19 03:14:07 2038
Tue Jan 19 03:14:08 2038
Tue Jan 19 03:14:09 2038
Tue Jan 19 03:14:10 2038

A recent example of the 2038 problem was documented on Wikipedia but without clues neiher a solution.

If you are working with Open Source code, this free library may be a useful reference for patching existing code for high-accuracy longterm time calculation: “libtai is a library for storing and manipulating dates and times. This is the kind of good timekeeping one might need for deep-space probes or high-reliability systems.

For more general applications, just using large types for storing dates will do the trick in most cases. For example, in GNU C, 64-bits (a “long long” type) is sufficient to keep the time from rolling over for literally geological eons. This just means any executables the operating systems runs will always get the correct time reported to them when queried in the correct manner. However it doesn’t stop the executables from having date issues of their own.

Probably soon we will see in GNU C something like a 64-bits type used for the type time_t of the standard time().
In a recent article by Jonathan Corbet looks like someone is seriously thinking about it but there is no definitive solution for now.

If anyone has updates or comments about, let me know. It’s a hot topic!