|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
KB931836 (Feb 2007 DST update) breaks DateTime historical DST calculationsthat 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 AM1 : 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 AM1 : 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 Finn,
That's a known problem. See http://msdn2.microsoft.com/en-us/vstudio/bb264729.aspx Mattias -- Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com Please reply only to the newsgroup. 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? |
|||||||||||||||||||||||