Perl, Programming

Fix Millennium Bug or y2038 Bug

Millennium Bug or y2038 Bug in Unix Machine

This post is dedicated to backend programmers mainly and especially who are involved with *nix machine(s) or Macintosh as well. It is similar to Y2K only where in many older machines, the year 2000 was treated as it starts from 1900 again. This time it is with all 32 bit (4 byte) Unix machines. It can store upto 231 i.e 2147483647. If you try to find which date it is, then it is Tue Jan 19 03:14:07 2038. Now after this it will be -2147483648 and will start the time counter as Fri Dec 13 20:45:52 1901

You can see the demonstration of above technical details at below image:

Y2038 or millenium bug demo
Y2038 or millenium bug demo

How it will affect the systems?

Whichever application(s) in 32bit systems uses Unix machine timestamp will get affected. It could be embedded software, COBOL language or even a website which sets future time in cookies which just gets beyond the 32bit time limit. It could be any medical or military device(s), even anything which uses GPS for communication.

You can read more about Y2038 bug at Wikipedia: http://en.wikipedia.org/wiki/Year_2038_problem

How to overcome this in our code?

There is only one 100% solution is convert all systems to 64 bit architecture which is not possible in many cases. Fixing this to display correct timing by changing the definition of time_t datatype is dependent on the nature of number systems that we are going to use in our programs.

So,I am giving you an example to overcome this bug using Perl module Time::y2038 which basically uses time_t datatype internally. So, wherever you are using gmtime, localtime, timegm ot timelocal now you need to use Time::y2038::gmtime and so on

Or just use Time::y2038::Everywhere and then write gmtime ot localtime etc it will take care of y2038 bug.

This link gives better idea on how it is being implemented: https://github.com/schwern/y2038/wiki

How to find out if the system is 32 bit or 64 bit ?
There are many commands in *nix, below command can be handy:


uname -m

Output will be either i686 (32 bit) or x86_64 (64 bit)

Once you have installed Time::y2038 in your 32 bit system, try below commands for better idea.


perl -e 'print time'
1420712903

perl -e 'print scalar localtime(1420712903)'
Thu Jan 8 02:28:23 2015

perl -e 'print scalar localtime(1420712903 + 24*60*60*365*25)'
Thu Nov 26 20:00:07 1903

perl -MTime::y2038::Everywhere -e 'print scalar Time::y2038::Everywhere::localtime(1420712903 + 24*60*60*365*25)'
Mon Jan 2 02:28:23 2040

 

Share your Thoughts