Tuesday 27 November 2007

Time Zones and .NET 3.5

Finally with the new .NET 3.5 framework release, Microsoft has given us the ability to convert to arbitrary time zones, and take into account historic changes to daylight savings rules. Before, this had to be done with interop, and even then you ran into all sorts of problems when trying to convert using time zones whose daylight savings information specified exact dates rather than nth Sunday of the month (e.g. the Israel / Jerusalem Standard time does this).

I did some testing today with the new TimeZoneInfo class, and all seems to be good. It works on both XP and Vista, and seems to be making use of the Dynamic DST registry keys under HKLM\Software\Microsoft\Windows NT\CurrentVersion\Time Zones (based on how many years back in time I can go before it starts getting it wrong).

One quirk compared to the old way I was converting local times back into UTC using the TzSpecificLocalTimeToSystemTime Windows API was that it now seems to guess the other way to before when given an ambiguous local time. A bit odd, but not a big deal.

Another thing I noticed is that the result of TimeZoneInfo.ConvertTimeFromUtc comes back with its DateTimeKind as Unspecified rather than as Local. I suppose this is because although it is a local time, it may not be the local time in the current locale. ConvertTimeToUtc does set the DateTimeKind to Utc as expected though.

On top of the TimeZoneInfo class, Microsoft have also given us a new DateTime structure - DateTimeOffset, which effectively allows you to store a local time with an explicit offset from UTC, giving you the best of both worlds. Switching to this from DateTime actually removes the need for TimeZoneInfo in most cases as you have the ability to get both the original LocalTime and the UTC time out of the same variable.

No comments: