As I’ve discussed time and time again, dealing with dates & times is hard, especially when you have to account for different times. The problem is made even more difficult when daylight savings time needs to be accounted for correctly.
Starting with .NET 1.0, Microsoft gave us some basic classes for dealing with these problems. The DateTime class allowed us to represent a specific point in time (though without explicit tracking for what time zone that point was represented in) and the TimeZone class, which gave access to information about the user’s current time zone (the time zone active on the computer), but not about time zones in general.
The TimeZone class did not allow you translate between arbitrary time zones, primarily because Microsoft did not want to take responsibility for keeping and updating a formal record for all time zones and the rules for conversion between them (remember, time zones and their policies on daylight savings time are determined by politics, not mathematical rules). Microsoft did release a best practices guide discussing the best ways to handle storage and computations when working with dates and times. I will leave a discussion of these best practices for a future post.
Starting with .NET 3.5, Microsoft has significantly improved the .NET representations of dates and times. They have introduced the DateTimeOffset and TimeZoneInfo. The DateTimeOffset class allows you to record the current offset in which the date & time is recorded (though not the actual time zone, which would determine daylight savings time observation). The TimeZoneInfo class allows conversion between arbitrary time zones, meaning Microsoft has finally taken responsibility for tracking information for time zones. They also provide a facility to define your own time zones, with appropriate rules for daylight savings time observation.
Dan Rigsby has a two part series where he looks primarily at the mechanical use of these classes. Part one discusses the use of the DateTimeOffset class and part two discusses the use of the TimeZoneInfo class.
In the future, I plan to discuss the use of these classes further, and look more closely at the potential problems that developers can run into even with these more advanced representations.