KB931836 (Feb 2007 DST update) breaks DateTime historical DST calculations

F

Finn Hart

The United States Daylight Saving Time rules are changing in 2007 so
that DST starts on the 2nd Sunday in March and ends on the first
Sunday in November. The previous DST rule was "First Sunday in April
through last Sunday in October".

Microsoft just rolled out the "February 2007 cumulative time zone
update for Microsoft Windows operating systems" (http://
support.microsoft.com/?kbid=931836) which contains the new US rules.

I assume - although I have not exhaustively checked - that the fix
does not effect dates prior to 2007. That is, the Windows API layer
should do the right thing when figuring out DST for years prior to
2007 vs. years from 2007 onward.

What I have checked, however, is the .NET "DateTime" class. It is
broken. Prior to installing the update, it correctly does DST for all
years prior to 2007. For 2007 onward, of course, it calculates DST
incorrectly because it uses the old rules.

AFTER installing the update, however, it is broken in the opposite way
- the DateTime class applies the NEW rules to all years, including
those prior to 2007.

This bug effects, at the least, the "IsDaylightSavingTime" and
"ToUniversalTime" methods of the DateTime object. (ToUniversalTime()
converts a local time into UTC time by adding the timezone's base
offset plus a DST adjustment, if the given local time is in DST per
the local rules ... thus it is broken as well).

Here's a short .aspx page running through the start of DST for 2006 &
2007:

-------------------------------------------------------------------------------
<%@ Import namespace="System.Globalization" %>
<%@ Page Language='c#' %>
<script runat=server>
private const string LN_FMT = "{0,-2}: {1,-25} -> {2,-25}";
private const string DT_FMT = "ddd MM/dd/yyyy hh:mm tt";

DateTime[] dates = new DateTime[] {
new DateTime(2006,3,12)
,new DateTime(2006,4,2)
,new DateTime(2007,3,11)
,new DateTime(2007,4,1)
};

private void DoDates() {
WriteLn(LN_FMT, "", "local", "toUniversalTime");
foreach (DateTime basedt in dates) {
for (int h=1; h<=4; h++) DoDate(basedt.AddHours(h));
Response.Write("\n");
}
}

int i=0;
private void DoDate(DateTime dt) {
string dstr = FmtDate(dt);
string ustr = FmtDate(dt.ToUniversalTime());

if (dt.IsDaylightSavingTime()) dstr += "**";

WriteLn(LN_FMT, i++, dstr, ustr);
}

private string FmtDate(DateTime dt) {
return dt.ToString(DT_FMT, DateTimeFormatInfo.InvariantInfo);
}

public void WriteLn(String fmt, params object[] args) {
Response.Write(String.Format(fmt,args) + "\n");
}
</script>

<html>
<body>
<pre>
<% DoDates(); %>
</pre>
</body>
</html>
-------------------------------------------------------------------------------

Here's the output without the Feb 2007 patch installed:

: local -> toUniversalTime
0 : Sun 03/12/2006 01:00 AM -> Sun 03/12/2006 09:00 AM
1 : Sun 03/12/2006 02:00 AM -> Sun 03/12/2006 10:00 AM
2 : Sun 03/12/2006 03:00 AM -> Sun 03/12/2006 11:00 AM
3 : Sun 03/12/2006 04:00 AM -> Sun 03/12/2006 12:00 PM

4 : Sun 04/02/2006 01:00 AM -> Sun 04/02/2006 09:00 AM
5 : Sun 04/02/2006 02:00 AM -> Sun 04/02/2006 10:00 AM
6 : Sun 04/02/2006 03:00 AM** -> Sun 04/02/2006 10:00 AM
7 : Sun 04/02/2006 04:00 AM** -> Sun 04/02/2006 11:00 AM

8 : Sun 03/11/2007 01:00 AM -> Sun 03/11/2007 09:00 AM
9 : Sun 03/11/2007 02:00 AM -> Sun 03/11/2007 10:00 AM
10: Sun 03/11/2007 03:00 AM -> Sun 03/11/2007 11:00 AM
11: Sun 03/11/2007 04:00 AM -> Sun 03/11/2007 12:00 PM

12: Sun 04/01/2007 01:00 AM -> Sun 04/01/2007 09:00 AM
13: Sun 04/01/2007 02:00 AM -> Sun 04/01/2007 10:00 AM
14: Sun 04/01/2007 03:00 AM** -> Sun 04/01/2007 10:00 AM
15: Sun 04/01/2007 04:00 AM** -> Sun 04/01/2007 11:00 AM

Notice that DST (denoted by ** and the repeated UTC time) starts
correctly on 4/2/06, and incorrectly (as expected) on 4/1/2007.

We would expect the fix to move only the 2007 start time (to
3/11/2007) without effecting the 2006 time. However, this is not the
case.

Here's is the output from a patched system:

: local -> toUniversalTime
0 : Sun 03/12/2006 01:00 AM -> Sun 03/12/2006 09:00 AM
1 : Sun 03/12/2006 02:00 AM -> Sun 03/12/2006 10:00 AM
2 : Sun 03/12/2006 03:00 AM** -> Sun 03/12/2006 10:00 AM
3 : Sun 03/12/2006 04:00 AM** -> Sun 03/12/2006 11:00 AM

4 : Sun 04/02/2006 01:00 AM** -> Sun 04/02/2006 08:00 AM
5 : Sun 04/02/2006 02:00 AM** -> Sun 04/02/2006 09:00 AM
6 : Sun 04/02/2006 03:00 AM** -> Sun 04/02/2006 10:00 AM
7 : Sun 04/02/2006 04:00 AM** -> Sun 04/02/2006 11:00 AM

8 : Sun 03/11/2007 01:00 AM -> Sun 03/11/2007 09:00 AM
9 : Sun 03/11/2007 02:00 AM -> Sun 03/11/2007 10:00 AM
10: Sun 03/11/2007 03:00 AM** -> Sun 03/11/2007 10:00 AM
11: Sun 03/11/2007 04:00 AM** -> Sun 03/11/2007 11:00 AM

12: Sun 04/01/2007 01:00 AM** -> Sun 04/01/2007 08:00 AM
13: Sun 04/01/2007 02:00 AM** -> Sun 04/01/2007 09:00 AM
14: Sun 04/01/2007 03:00 AM** -> Sun 04/01/2007 10:00 AM
15: Sun 04/01/2007 04:00 AM** -> Sun 04/01/2007 11:00 AM
 
I

ICE

Why is the U.S. still switching their clocks by an hour twice a year?
This is not a farming society (anymore). This outdated practice just
causes many problems with computers and also with people. It's painful
to have to wake up an hour earlier just so that at bedtime the kids
can't go to sleep because there is full sunlight coming in through the
windows.

Most people are in an office or at school most of the day so we'll be
using artificial light regardless of the clock.
For those who work outside in the northern hemisphere, they're getting
longer days already in the summer without having to change the clock.

So, really nobody wins - Daylight Savings Time should be abolished!
Especially "Spring forward" ... we can do one more "Fall back" to get
an extra hour of sleep and then leave the clocks alone. Is there a
political group or grassroots organization I can join or send money to
get this change in the Constitution?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top