The impending Unix Y2038 bug, caused by 32-bit signed integer limits, poses significant quality assurance challenges for date-time values in software development. Mitigating this risk requires transitioning hardware, operating systems, and application layers to 64-bit architectures to ensure long-term system stability.
How to Assure Quality in Date-Time Values in Software Development
article
To understand why QA is critical for date-time values, we only need to look back to 1999; despite advanced database technology, the Y2K bug still occurred. When database software developers first developed programs, they must not have been anticipative enough. The Y2K issue would not have happened if the year field in a date were stored only as a complete value; for example, ‘1970’, instead of ‘70’. Thereafter, the British Standards Institution committee laid out the rules for Year 2000 conformity.
However, software developers still need to be aware of similar potential issues that could occur in the future related to date-time values.
Using Four or Two Digits to Store a Year Value
Ideally, specify a Year value as a four-digit number. However, if one still prefers two-digit values, some databases such as MySQL, and Oracle, do support it. However, note that the logic used by MySQL and Oracle for storing 2-digit year values involves guesswork. Therefore, if 2-digit year values must be encoded, it is recommended to perform a code review periodically to ensure that values are stored as designed. This is because how databases guess the year is likely to change. Admittedly, it wouldn’t be prudent to store ‘70’ as ‘1970’ in 2070, as databases store today! That is why it is recommended to specify the year as a four-digit value, always.
A Three-Tiered Approach to Y2038 Mitigation (Hardware, OS, and Application Layer)
First, let’s introduce what the Unix time Y2038 bug is.
A date and time best practice that developers need to be aware of in computing is to not use Unix time for storing date-time data. The Unix time system measures time in non-leap seconds, starting at 00:00:00 UTC on 1 January 1970, the Unix epoch. It stores value as a signed 32-bit integer. Anyone familiar with binary math can calculate that the maximum value a signed 32-bit integer can hold is represented by 01111111 11111111 11111111 11111111, which implies that a computer system using Unix time can't represent a date value after 03:14:07 UTC on 19 January 2038.
Hardware
As a general recommendation, use 64-bit hardware architecture. Hardware support can be verified with the lscpu command. The command output should be similar to the following:
lscpuArchitecture: x86_64
Use embedded systems that use the 64-bit hardware architecture and use 64-bit date-time based software. A clock in routine use showing an incorrect time when the year 2038 rolls over is not a cause for concern, because it is similar to having to set a clock forward/backward at Spring daylight saving start/end, if a clock is not set automatically. However, it is a critical issue in some embedded systems. While it is relatively easier to update software in larger computer systems, embedded systems are generally not designed for updates. This means that older 32-bit based embedded systems will fail after the aforementioned date - 03:14:07 UTC on 19 January 2038.
As an example, Automatic Four-Wheel Drive systems, especially older models that store delta-time values commonly used for detecting skids and managing traction as signed 32-bit integers, are susceptible to the Y2038 bug. As the Y2038 bug date rolls over, an embedded system like the one used in an automatic four-wheel drive will get into a rollover stuck state, referring to the state after time rolls over the supported timestamp range. Therefore, when automobile designers became aware of the Y2038 bug, they developed newer automobile models using 64-bit integer values based code and ECUs (Electronic Control Units). Accordingly, modern automobile Electronic Control Units (ECUs) are based on a 64-bit architecture, and when used with time_t as a 64-bit integer, fix the Y2038 issue. This means that the anti-skid feature in a four-wheel drive will function correctly even after 2038.
Operating System
To avoid the Y2038 bug, use the 64-bit Linux distributions on 64-bit hardware. If using a 32-bit distribution such as the Debian 12 (Bookworm) stable release, it’s best to upgrade to a 64-bit one. Ubuntu has completely discontinued standalone 32-bit (x86/i386) installation images.
Software Applications
If one is already using software that uses the Unix time, it is best to update it to use one that uses a signed 64-bit integer to store date-time values, or at least an unsigned 32-bit integer to defer the issue till 2106.
Which Date-Time Functions to use? Use date-time functions that store value as a 64-bit signed integer. Database functions like the UNIX_TIMESTAMP() in MySQL (versions prior to 8.0.28) store timestamps as signed 32-bit integers; therefore, they become unusable after the Y2038 bug takes effect. Use MySQL 8.0.28 and later versions running on 64-bit platforms extend the valid range of argument values for UNIX_TIMESTAMP() that uses 64-bit signed decimal/integer (BIGINT).
Any legacy code that compares/stores date and time values using the signed 32-bit integers will fail, or provide erroneous results. For example, the time_t function in C language is a 32-bit based signed integer. To fix this, use the GNU C Library version 2.34, which adds support for 64-bit time_t on configurations like x86, where it is traditionally 32-bit. Internally it calls a new 64 bit signed integer implementation, _time64( __time64_t *destTime ). There is legacy support in the newer functions if needed. As an example, the new time_t function can be used as the old 32-bit time_t by defining the _USE_32BIT_TIME_T switch.
In Java, which has extensive use in embedded applications, the JVM's (Java Virtual Machine) System.currentTimeMillis() returns the result as a long primitive type (a signed 64-bit integer). Similarly, the java.time.Instant.getEpochSecond() function returns a signed 64-bit long representation of Unix seconds to avoid Y2038 integer truncation.
Further, use data types that support 64-bit signed integers to store data-time values, like the 64-bit Signed Integer (BIGINT) data type.
Lets Hang!