Wild Bug in Date Conversion Code

bug.gif

We came across a very wild bug today with date conversions. Basically, the problem is taking an option's expiration in the form YYYYMMDD and seeing if that date falls on a weekend. If it does, then back it off to the Friday before the weekend. The original code I had made use of mktime()'s ability to compute the "day of the week" given the year, month and date:

  struct tm  when;
  // will this struct up with the date as we know it
  when.tm_year = aDate/10000;
  when.tm_mon = (aDate - (when.tm_year*10000))/100;
  when.tm_day = (aDate - (when.tm_year*10000) - (when.tm_mon*/100);
  // correct the values for the call to mktime()
  when.tm_year -= 1900;
  when.tm_mon -= 1;
  // now call mktime() and let it fill in when.tm_wday...
  mktime(&when);
  if (when.tm_wday == 0) {
    // it's a Sunday!
  }

what we were seeing was that the day of the week was all wrong. In fact, the year, month and date coming back from mktime() were being randomly scrambled. Very odd.

The solution was simple - zero out the struct before using it. Sounds simple. But you'd think the compiler would do this for you. Nope. it's uninitialized memory. Silly me.

The fix looks remarkably similar - save one line:

  struct tm  when;
  bzero(&when, sizeof(when));
  // will this struct up with the date as we know it
  when.tm_year = aDate/10000;
  when.tm_mon = (aDate - (when.tm_year*10000))/100;
  when.tm_day = (aDate - (when.tm_year*10000) - (when.tm_mon*/100);
  // correct the values for the call to mktime()
  when.tm_year -= 1900;
  when.tm_mon -= 1;
  // now call mktime() and let it fill in when.tm_wday...
  mktime(&when);
  if (when.tm_wday == 0) {
    // it's a Sunday!
  }