Click here to Skip to main content
Click here to Skip to main content

User Interface Time Zone Extending the System.TimeZone Class

, 29 Aug 2007
Rate this:
Please Sign up or sign in to vote.
Using the System.TimeZone class to allow users of your applications to specify their time zone preferences

Introduction

Imagine you are developing a Web or desktop application where you need to work with DateTime values in a time zone specified by the user's preference. I got myself into such a situation several weeks ago and I started to search the Web for a suitable solution. Unfortunately I didn't find anything I liked, so I started to design my own solution.

The first article I took into consideration was Mike Dimmick's WorldClock article here on The Code Project. If you need to convert DateTime values from/to various time zones, this could be an acceptable solution. But it was not my case exactly because I just was to convert times from/to UTC values, so I came to the conclusion that I needed to extend the abstract System.TimeZone class provided by the .NET Framework. Furthermore, Mike's code doesn't really comply with my sense of object oriented design, no offence.

You may also find it useful to use the Olson time zone database, but remember that you will need the PublicDomain DLL installed in the GAC and you will have to care about the database updates.

UITimeZone and TimeZoneManager

UITimeZone class design

As you can see in the picture above, the required functionality is implemented by two cooperating classes. There is a UITimeZone class that derives from the abstract System.TimeZone class. The TimeZone class contains a property called CurrentTimeZone which can be used to obtain the current time zone of the machine executing the calling assembly - in case of a Web application, this could be the time zone of the Web server. Similarly, the UITimeZone class provides the CurrentUITimeZone property that can be used to get or set the time zone of the user interface. It is an analogy of the CurrentCulture and CurrentUICulture properties of the Thread class.

The TimeZoneManager class has no special meaning; it's just a static class providing a list of available time zones and an implementation of the Greenwich Mean Time time zone that could be used as a default value in some scenarios. The list of available time zones is retrieved from the time zone database placed in the Windows registry, so you can rely on Microsoft to update the database when needed. But if you want to be perfect, you should monitor the Windows registry for changes and reload the collection of available time zones every time a modification is made to the time zone database.

If you need more detailed information about time zones and about the way time zones are organized in the Windows registry, see the Mike Dimmick's article or refer to the MSDN Library.

System.TimeZone Issues

There are several reasons why one should not try to use the System.TimeZone class as a base class. In my Web search for time zone solutions, I've found a thread in the MSDN Forums where a member of the Base Class Libraries development team classifies the attempt to make TimeZone a point of extensibility as a mistake. First of all, it is unclear what the ToLocalTime() method should do, whether it should convert from the represented time zone to the machine time zone or from UTC to the represented time zone. I see the latter perfectly suitable for the case of UITimeZone, because it seems clear to me that TimeZone.CurrentTimeZone.ToLocalTime() converts to machine local time, and UITimeZone.CurrentUITimeZone.ToLocalTime() converts to user local time. But I can understand that this could be a matter of opinion.

Another issue does not refer directly to the TimeZone class, but rather to the internal CurrentSystemTimeZone class that is used in the implementation of the TimeZone.CurrentTimeZone property. The problem doesn't appear until you need to work with historical data. Some of the existing time zones use so called Dynamic Daylight Saving Time which means that the dates and times at which the changes to and from Daylight Saving Time occur differ from one year to another. The CurrentSystemTimeZone class always uses the actual daylight saving time rules, whether the year of the processed time equals to the current year or not. Dynamic daylight changes are stored in the Windows registry, but neither .NET API nor Win32 API (except Windows Vista) provides functionality of querying this data. If you need to work with historical data, which should be the case in database applications and information systems, you may use the UITimeZone class because it handles historical data correctly.

Using the Code

First of all, you need to implement your own logic of retrieving and updating the user's time zone setting. The sample provided with this article stores the user preferences just in memory, so it is lost when the application ends.

/// <summary>
/// Gets or sets the time zone of the current user.
/// </summary>
public static TimeZone CurrentUITimeZone
{
    get
    {
        string userName = Thread.CurrentPrincipal.Identity.Name;
        //TODO: add your retrieving logic here
        return TimeZoneManager.GmtTimeZone;
    }
    set
    {
        string userName = Thread.CurrentPrincipal.Identity.Name;
        //TODO: add your updating logic here
    }
}

The following code snippet shows how to use the current user interface time zone. Note that DateTime values retrieved from a database used to have their Kind property set to DateTimeKind.Unspecified, but it may differ with the particular database provider you might be using.

TimeZone currentUITimeZone = UITimeZone.CurrentUITimeZone;

DateTime dbValue = GetDateFromDatabase();
DateTime local = currentUITimeZone.ToLocalTime(dbValue);

local = GetDateFromUser();
dbValue = currentUITimeZone.ToUniversalTime(local);

When you need to modify the user interface time zone, you can use the machine time zone, the Greenwich Mean Time time zone, or you can face the user with a drop-down displaying the list of available time zones which is provided by the TimeZoneManager class.

// Sets the UI time zone equal to the machine time zone
UITimeZone.CurrentUITimeZone = TimeZone.CurrentTimeZone;

// Sets the UI time zone to be the Greenwich time zone
UITimeZone.CurrentUITimeZone = TimeZoneManager.GmtTimeZone;

// Sets the UI time zone to be the 34th known time zone
UITimeZone.CurrentUITimeZone = TimeZoneManager.TimeZones[33];

// Sets the UI time zone to be the Prague's time zone
UITimeZone.CurrentUITimeZone =
    TimeZoneManager.TimeZones["Central Europe Standard Time"];
Drop-down list sample

Conclusion

Hopefully, enumerating the time zones and more will be soon directly supported by the .NET Framework and its TimeZoneInfo class. Until the .NET Framework 3.5 is released, you might find my classes useful, and I will appreciate any feedback on them. Also feel free to report any bugs discovered in my code. Thanks.

History

  • 29th July, 2007: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

kublaj
Software Developer (Senior)
Czech Republic Czech Republic
Jakub Novák (yes, this is his real name Smile | :) ) is a professional in the domain of information technologies in which he has been working since the year 2000. He's got a doctorate in Design and Process Engineering; during his PhD study he performed tasks of a consultant and analyst of the software parts of problems and was responsible for development of execution routines from the area of digital signal processing.
 
He's experienced in analysis and design of software applications using the techniques of OOP and UML and in development of computer programs in C++, C# and Visual Basic languages. He is very interested in new technologies.
 
Currently he works as a freelance senior software developer participating in stand-alone interesting and challenging projects.

Comments and Discussions

 
GeneralThere is a logical bug in the class implementation. [modified] PinmemberVBDT10-Sep-07 7:59 
GeneralRe: There is a logical bug in the class implementation. Pinmemberkublaj18-Sep-07 12:04 
GeneralRe: There is a logical bug in the class implementation. PinmemberVBDT18-Sep-07 13:38 
GeneralRe: There is a logical bug in the class implementation. Pinmemberkublaj22-Sep-07 1:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140823.1 | Last Updated 29 Aug 2007
Article Copyright 2007 by kublaj
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid