The documentation for the .NET DateTime.ToLocalTime method states:
On Windows XP systems, the ToLocalTime method recognizes only the current adjustment rule when converting from UTC to local time. As a result, conversions for periods before the current adjustment rule came into effect may not accurately reflect the difference between UTC and local time.
I'm developing on Windows 7 but deploying to a mixed environment. How can I provide a consistent, correct implementation that matches the Windows 7 behavior of ToLocalTime?
EDIT
I ran a test:
static void Main()
{
// 8 AM in July, UTC. That would have been DST, so 3 AM CDT.
var dstDate = new DateTime(2010, 7, 1, 8, 0, 0, DateTimeKind.Utc);
// 8 AM in December, UTC. Not DST, so 2 AM CST.
var nonDstDate = new DateTime(2010, 12, 1, 8, 0, 0, DateTimeKind.Utc);
Log("DST Date ToLocalTime: " + dstDate.ToLocalTime());
Log("DST Date ConvertTimeFromUtc: " + ConvertTimeFromUtc(dstDate));
Log("Expected: 3 AM July 1 2010");
Log(string.Empty);
Log("Non-DST Date ToLocalTime: " + nonDstDate.ToLocalTime());
Log("Non-DST Date ConvertTimeFromUtc: " + ConvertTimeFromUtc(nonDstDate));
Log("Expected: 2 AM December 1 2010");
Log(string.Empty);
Log("Date ToLocalTime Kind: " + dstDate.ToLocalTime().Kind);
Log("Date ConvertTimeFromUtc Kind: " + ConvertTimeFromUtc(dstDate).Kind);
}
private static void Log(string message)
{
Console.WriteLine(message);
}
private static DateTime ConvertTimeFromUtc(DateTime utcDateTime)
{
return
DateTime.SpecifyKind(
TimeZoneInfo.ConvertTimeFromUtc(
utcDateTime,
TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id)),
DateTimeKind.Local);
}
The results were identical under XP Pro 32-bit, SP3 (as VM) and Windows 7 Enterprise 64-bit:
DST Date ToLocalTime: 7/1/2010 3:00:00 AM DST Date ConvertTimeFromUtc: 7/1/2010 3:00:00 AM Expected: 3 AM July 1 2010 Non-DST Date ToLocalTime: 12/1/2010 2:00:00 AM Non-DST Date ConvertTimeFromUtc: 12/1/2010 2:00:00 AM Expected: 2 AM December 1 2010 Date ToLocalTime Kind: Local Date ConvertTimeFromUtc Kind: Local
Is the documentation wrong? Can I simply call ToLocalTime?
EDIT 2
We ran this on an actual XP system (not a VM) and got identical results there as well. Are my test cases correct? Can anyone provide a case where the results will differ?
On Windows XP systems, the ToLocalTime method recognizes only the current adjustment rule when converting from UTC to local time. As a result, conversions for periods before the current adjustment rule came into effect may not accurately reflect the difference between UTC and local time.
The US changed the adjustment rule for DST in 2007.
The bug is that they're following the 2007 rules for all dates, not just dates after 2007. The DST rules hadn't changed in 20 years, Windows XP just doesn't have the concept of different rules for different years. It will consider October 31, 2006 to be in Daylight Savings, when it actually wasn't.
If you're only dealing with dates after 2007, then you're good, no need to do anything special. If you're dealing with dates in or before 2006, then you'll need to check the year, and apply the DST offset manually.
You can use the System.TimeZoneInfo.ConvertTime(DateTime, TimeZoneInfo, TimeZoneInfo) method to convert the time from the source's timezone to the user's local timezone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With