Click here to Skip to main content
15,881,882 members
Articles / Web Development / ASP.NET
Article

User Interface Time Zone Extending the System.TimeZone Class

Rate me:
Please Sign up or sign in to vote.
4.04/5 (7 votes)
29 Aug 2007CPOL5 min read 61.4K   593   25   16
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.

C#
/// <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.

C#
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.

C#
// 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)


Written By
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

 
Questionnon-English XP systems Pin
Zhi Chen9-Dec-08 13:13
Zhi Chen9-Dec-08 13:13 
GeneralRe: non-English XP systems Pin
kublaj10-Dec-08 4:04
kublaj10-Dec-08 4:04 
GeneralIncorrect assumption about GMT Pin
Jim Parsells12-Oct-07 17:56
Jim Parsells12-Oct-07 17:56 
AnswerRe: Incorrect assumption about GMT Pin
kublaj5-Nov-07 4:28
kublaj5-Nov-07 4:28 
GeneralThere is a logical bug in the class implementation. [modified] Pin
Arman Ghazanchyan10-Sep-07 7:59
Arman Ghazanchyan10-Sep-07 7:59 
Hi, this is nice what you did but I can see a major bug in your code by looking on it. In particular the bug is in the GetUtcOffset method. This is a logical bug, for example let say I am in Yerevan (Armenia) and I want to get the UtcOffset of Brazil. The method takes a local time or any time other then Brazil’s and uses its year property to retrieves the settings of the time zone. Let say that it happens that I am retrieving the Brazil’s UtcOffset on the new year evening Yerevan at 01/01/2008 2:00 am. What would happen is that I would get a wrong UtcOffset (Standard base) since in Yerevan it would be 2008 and in Brazil it still would be 2007 so IsDaylightTime method will return false and in Brazil it is daylight saving time in general (during November through February).

There are some other issues with implementation that I will mention only one, the code adds the TZI registry entry in to a dictionary for quick access but this is not right since the registry might be updated by MS with critical windows update and this value would not be updated. Just a thought.


-- modified at 14:26 Monday 10th September, 2007
GeneralRe: There is a logical bug in the class implementation. Pin
kublaj18-Sep-07 12:04
kublaj18-Sep-07 12:04 
GeneralRe: There is a logical bug in the class implementation. Pin
Arman Ghazanchyan18-Sep-07 13:38
Arman Ghazanchyan18-Sep-07 13:38 
GeneralRe: There is a logical bug in the class implementation. Pin
kublaj22-Sep-07 1:50
kublaj22-Sep-07 1:50 
GeneralA Possible Bug Pin
rami2715-Aug-07 6:54
rami2715-Aug-07 6:54 
GeneralRe: A Possible Bug Pin
rami2715-Aug-07 7:37
rami2715-Aug-07 7:37 
GeneralRe: A Possible Bug Pin
kublaj15-Aug-07 9:18
kublaj15-Aug-07 9:18 
AnswerRe: A Possible Bug Pin
kublaj29-Aug-07 4:15
kublaj29-Aug-07 4:15 
GeneralArtihmatic Overflow Pin
Zisha3-Aug-07 7:55
Zisha3-Aug-07 7:55 
GeneralRe: Artihmatic Overflow Pin
kublaj3-Aug-07 10:35
kublaj3-Aug-07 10:35 
GeneralRe: Artihmatic Overflow Pin
Zisha6-Aug-07 12:41
Zisha6-Aug-07 12:41 
GeneralRe: Artihmatic Overflow Pin
kublaj7-Aug-07 10:19
kublaj7-Aug-07 10:19 

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

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