COMMAND
The Windows "April Fools 2001" bug
SYSTEMS AFFECTED
Win9x, NT
PROBLEM
Richard M. Smith found following. He has discovered a serious bug
in Windows which will cause many Windows applications to give the
incorrect time starting on April 1, 2001. Although this new bug
is not technically a Y2K bug, it is similar because programs will
fail on a particular day in the next century. The bug causes
Windows applications to give times which are off by one hour even
though the Windows clock shows the correct time. The bug will
continue for one week until April 8th of 2001, when applications
will again show the correct time. The bug occurs under Windows
95, 98, and NT.
A bit of background. In the United State and Canada, daylight
saving time (DST) always starts on the first Sunday in April and
ends on the last Sunday in October. More information of the DST
rules can be found in the article at
http://www.energy.ca.gov/daylightsaving.html
The problem is caused by the Visual C++ runtime library being
confused and assuming that daylight saving time doesn't start
until April the 8th. In fact, daylight saving time starts on
April 1 in the year 2001. The confusion appears to be caused by
the fact that April 1 falls on a Sunday in the year 2001. The
same bug occurs in other years where April 1 also falls on a
Sunday. The last time this happened was in 1990 and after 2001 it
will occur again in 2007. If April 1 falls on any other day of
the week, the bug does not occur.
Richard created a live demo page on the Web that tests for the bug
in Netscape Navigator 4 and Internet Explorer 4 which both
apparently use Visual C++ runtime library. The URL of this demo
page is:
http://security.pharlap.com/y2k/demo1.htm
Richard believes that the bug was introduced in version 4.1 of
Visual C++. It is present in versions 4.2, 5.0, and 6.0 according
to his testing. He has written a small program in C that tests
for the problem. The source code for the test program is below.
This "April Fools 2001" bug is present in the localtime()
function, but is probably also in other functions defined in the C
language "time.h" header file.
//
// APRIL1.C -- Simple test program for the "April's Fools 2001" bug
//
// by Richard M. Smith (rms@pharlap.com)
// copyright (C) 1999
//
#include <stdio.h>
#include <time.h>
#include <string.h>
#define SECS_PER_HOUR (60 * 60)
#define SECS_PER_DAY (24 * SECS_PER_HOUR)
#define SECS_PER_YEAR (365 * SECS_PER_DAY)
#define START (3 * SECS_PER_DAY)
#define INCR (23 * SECS_PER_HOUR)
#define MAXTIMES ((0x80000000L - START) / INCR)
void print_time(time_t mytime);
char *month_tab[] =
{
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};
char *dow_tab[] =
{
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
};
int main()
{
print_time(0x3AC796D0); // Sunday, April 1, 2001
print_time(0x3ACF2B70); // Saturday, April 7, 2001
print_time(0x3AD06EE0); // Sunday, April 8, 2001
return 0;
}
//
// print_time -- print out a time_t value converted by localtime()
//
void print_time(time_t mytime)
{
char month[100];
char dow[100];
struct tm *tmp;
tmp = localtime(&mytime);
if(tmp == NULL)
{
printf("0x%08lX = Invalid time\n", mytime);
return;
}
if(tmp->tm_mon >= 0 && tmp->tm_mon <= 11)
strcpy(month, month_tab[tmp->tm_mon]);
else
sprintf(month, "BadMonth=%d", tmp->tm_mon);
if(tmp->tm_wday >= 0 && tmp->tm_wday <= 6)
strcpy(dow, dow_tab[tmp->tm_wday]);
else
sprintf(month, "BadDOW=%d", tmp->tm_wday);
printf("0x%08lX = %s, %s %d, %d -- %d:%02d:%02d %s -- DOY=%d\n",
mytime, dow, month, tmp->tm_mday, tmp->tm_year + 1900,
tmp->tm_hour, tmp->tm_min, tmp->tm_sec, _tzname[tmp->tm_isdst != 0],
tmp->tm_yday);
return;
}
SOLUTION
Microsoft is mentioning fixes available for the April Fools 2001
bug in msvcrt.dll
http://msdn.microsoft.com/visualc/headlines/2001.asp
MS includes 2 utilities in the NT Resource Kit, both designed to
(at least in part) address Daylight Savings Time issues:
TZEdit.exe and Timezone.exe.
TZEdit.exe allows you to edit all Time Zones, and even create new
ones. Timezone.exe allows you to specify exact dates for start
and end of DST. This utility would be useful if your DST was not
based on, e.g., 1st Sunday of April, but instead based on 5th of
April every year. Timezone.exe makes its changes directly in the
registry. Using Timezone.exe means you will have to run it every
year! Since it records the start and end dates for DST as exact
dates, as opposed to relative dates, you'd have to change them
over and over again. TZEdit does a better job, but it can't
overcome the problems described by Richard Smith.