I had an interesting encounter with the end of time at work today. There are times when our Unix based application deliberately sets a date value to the end (19-Jan-2038) to signify some special scenario. We never passed on this value to our Windows based front end program ever, until today, by accident. And yes, Hell most certainly did break loose. Luckily for us, not in production, just in our Analysts environment.
The issue was that our VC++ made Windows program refused to see 19-Jan-2038 as the end. It saw 18th Jan 2038 as the end and hence mktime() would return with an error for 19-Jan-2038. But this was not the funny bit; read on.
So as I was saying, when I assigned my
struct tm as follows:
t.tm_mday = 19; t.tm_mon = 0; t.tm_year = 2038 - 1900; t.tm_hour = 0; t.tm_min = 0; t.tm_sec = 0;
and used mktime() on it, the result would be mktime() returning an error status (-1). So next, I assigned my struct as:
t.tm_mday = 18; t.tm_mon = 0; t.tm_year = 2038 - 1900; t.tm_hour = 23; t.tm_min = 59; t.tm_sec = 60;
Bingo, a subsequent call to mktime with this struct gave me 19-Jan-2038 00:00:00. Then I did the first one again and it worked this time -- magic!
I kept incrementing the seconds till I came up to the actual End of Time with:
t.tm_mday = 19; t.tm_mon = 0; t.tm_year = 2038 - 1900; t.tm_hour = 3; t.tm_min = 14; t.tm_sec = 7;
and it would not go any further than that. Whats more, 2^31 actually comes up to 19-Jan-2038 08:44:07 IST (UTC+5:30), which is where our Unix time ends as well. Windows doesn't get there with mktime().
So finally I did this as well, just to confirm:
j = 0x7ffffffe; /* This is 2^31 */ t2 = *localtime (&j); if (mktime (&t2) == -1) perror ("Even this fails"); else printf ("High Time: %s\n", asctime (&t2));
And it worked, showing 19-Jan-2038 08:44:07.
Hence, mktime() in Windows XP SP2 is probably buggy. Hopefully it has been patched in Windows update. Either ways, we're staying away from the End for now :^)