2038 bug starting to appear

After the Y2K hubbub was calmed down by intense and NECESSARY programming work, the next date problem will be in 2038, when the number of seconds since Jan 1, 1970 overflows a 32-bit integer. Newer systems store time in a 64-bit integer, which won’t overflow for hundreds of billions of years.

This item in the Reddit section making fun of software bugs shows that 2038 is already popping up.

The 2038 limit is less excusable than the old Y2K limit. By the time Windows was developed, punch cards were gone and computers were routinely dealing with larger data fields. Early PC registers were 16 bits, but it was easy to process a 64-bit integer in memory.

= = = = =

Reprint from last year:

Somebody mentioned the 25th anniversary of the Y2K mess. The problem was genuine but somewhat limited. Media panicators and provocateurs turned it into a full nuclear catastrophe. Provocateurs on the fake opposite side insisted it was much ado over nothing.

The reality was a LOT of hard work by real programmers to avoid a serious problem with SOME important computers, especially in banking and finance where mortgages and insurance policies could become unenforceable with “time-machine” situations. A mortgage might try to charge negative interest, which could generate a payment instead of a bill. An insurance policy payable in 2002 would become payable in 1902.

The limit was punch cards, not computers. Mainframes could handle large numbers in memory and math. For instance the IBM 650 (introduced in 1957) handled 10-digit decimal numbers, so a 4-digit date would be easy. Programmers took shortcuts to fit data into 80-column punch cards. One card might hold a transaction number, date, customer name, model number of purchased item, and price. Each digit was precious.

Everybody got into the act. I was writing commercially published courseware for Windows. Windows has four-digit dates, but some programmers continued the old habit of using only the last two digits. The publisher required me to check all dates and times in my program and report them officially. Courseware records grades, so the program did write dates and times. All were 4-digit, no problem.

I had to print out the entire source code on paper and send a form with my notarized signature guaranteeing correctness. The printout was a 50-pound box of folded dot-matrix paper.

Yes, Y2K was serious, but not an asteroid striking the earth.

Older Windows programs will get their chance to fail in 2038, when the 32-bit integer used as the base of time calculations will roll over to zero. Newer compilations generally use a 64-bit integer, but I’m pretty sure my program was compiled using the older standard. Fortunately my Windows program was no longer sold after the courseware switched to online form in 2014.

= = = = =

Just for fun, here’s the part of my code that writes the student’s grades along with the date.

 GetLocalTime(&Date);
 // Run up the basic info, updating the CheckSum.
 Sum = 0;
 GradeLine.s.month     = Num = Date.wMonth;        Sum += Num;
 GradeLine.s.day       = Num = Date.wDay;          Sum += Num;
 GradeLine.s.year      = Num = Date.wYear;         Sum += Num;
 GradeLine.s.LsnNumber = Num = atoi(gLsnBaseName); Sum += Num;
 GradeLine.s.Answered  = Num = TotalAnswered;      Sum += Num;
 GradeLine.s.Correct   = Num = TotalCorrect;       Sum += Num;
 GradeLine.s.Possible  = Num = gTotalPossible;     Sum += Num;
 GradeLine.s.NameLen   = Num = strlen(gGivenID);   Sum += Num;
 // Fill in the name manually, adding each char value to the sum;
 // after we use up the name, continue filling with random junk
 // so that our key string doesn't pop up when the 
 // grade file is viewed.
 short c;
 for (i=0; i < sizeof(GradeLine.s.Name); i++)
  {
   if (i<strlen(gGivenID))
    {
     c = (short)gGivenID[i];
     Sum += c; // Include name but not random in the sum.
    }
   else
    {
     c = (short)rand();
    }
   GradeLine.s.Name[i] = c;
  }
 // Put in the cksum of everything except the random fill.
 // Reminder: this action happens after the name-and-random fill,
 // even though the CkSum goes before the fill.
 GradeLine.s.CkSum     = Sum;
 // Cipher this by the key string, rerunning as usual.
 for (i=j=0; i<GRADELINELEN; i++,j++)
  {
   if (j==sizeof(gCodeKey)) j=0; // Rerun codekey if we go beyond it
   GradeLine.b[i] ^= (BYTE)gCodeKey[j];
  }
 // Write this to the GRD file.
 WriteFile(hfGrade,GradeLine.b,GRADELINELEN,&written,NULL);
 CloseFile(hfGrade);

= = = = =

In retrospect I probably should have included the time along with the date. In a question of cheating, the time when each student finished could settle who was first.

Note that I was simply using the wYear member of the standard Windows DATETIME struct, which always included all 4 digits of the year, so the Y2K problem couldn’t happen. If the compiled Windows code was using seconds and a 32-bit integer in its figuring, it could fail in 2038.

Note also my roll-your-own cybersecurity. This was before the modern web and before LMS systems. The students had to supply their own 3.5″ floppy, or in the later versions a USB stick. The program started with a function to choose your password, which was then encoded in a key file on the floppy. On each use of the program to run a lesson, the grade was ciphered using the password so it couldn’t be easily read by a casual thief. The checksum was mainly to detect accidental degradation of the floppy, not to guard against hackers.