The sample above gets all the time zone names and then gets the corresponding ZoneInfo.Zone instance.

From this instance, you can do a number of things like getting the local time in that zone and its current UTC offset.

Zone: Europe/Malta
has a local date time of 8/04/2008 9:40:52 AM
which is a GMT offset of 02:00:00
Zone: Europe/Minsk
has a local date time of 8/04/2008 10:40:52 AM
which is a GMT offset of 03:00:00
Zone: Europe/Monaco
has a local date time of 8/04/2008 9:40:52 AM
which is a GMT offset of 02:00:00
Zone: Europe/Moscow
has a local date time of 8/04/2008 11:40:52 AM
which is a GMT offset of 04:00:00

One of the most useful features of the API is the ability to convert arbitrary dates between time zones. A lot of TimeZone APIs only really know what the UTC offset is right now, not 6 months from now.

If you store dates in the database in UTC and need to convert them to the local time of the user, you need to apply a UTC offset. What happens if the daylight offset changes within this window? Well, you can know if this is the case rather than assuming that it doesn't matter.

Points of Interest

The code seems to work well for Australia and the other zones I have tested this with. I am sure as more people use it in different scenarios, it will continue to mature.

One thing I did notice was just how un-standard the format of the tz database was with respect to tab and space delimiting of fields ... the code has a number of hacks unfortunately to compensate this.

More Information

If you have any issues, please log it there and I will look at any changes which need to get done.

History

7th April, 2008: Initial post

There are still a number of things to be done including handling of Link entries in the files. The current format allows for backward compatibility in the old names. This is not hard to do and will happen soon (or if someone needs it).

Hello,
I want to report that we have successfully ported your project to a Silverlight 5 class library. After creating the library project, we copied Database.cs, Rule.cs, Zone.cs, and ZoneRule.cs to it. We built the project and were pleasantly surprised to find that there was only one line of code that needed to be changed!
In Database.cs, we changed LoadFiles() to use Directory.EnumerateFiles() rather than Directory.GetFiles(). In Silverlight, the later does not exist. Otherwise, everything seems to be working great! Here is the updated method:
<prelang="c#">
/// <summary>
/// Load all the zone files
/// </summary>
/// <paramname="directory">The directory containing the zone files</param>
/// <remarks>This method just iterates through all the files
/// and calls LoadFile on each, ignoring the .tab, .sh and factory files for now.</remarks>
public static void LoadFiles(string directory)
{
#if SILVERLIGHT
IEnumerable<string> files = Directory.EnumerateFiles(directory);
#else
string[] files = Directory.GetFiles(directory);
#endif
foreach (string file in files)
{
// Ignore the .tab and .sh files
// Also the factory and leapsecond files
// This is pretty crude but does the job
if (file.EndsWith(".tab") || file.EndsWith(".sh")
|| file.EndsWith("\\factory") || file.EndsWith("\\leapseconds")
)
continue;
// Now load each of the files
LoadFile(file);
}
}

Thank you very much for creating such a lightweight and useful API! It is especially important to Silverlight developers because Microsoft does not include TimeZoneInfo in Silverlight, so the only conversions that can be performed are UTC -> local and local -> UTC.

Maybe I have missed something, but I have trouble getting the computer's local time zone out of the tz database. I use .NET 3.5 where TimeZoneInfo is added. I get the local Windows time zone by
string tz_id = TimeZoneInfo.Local.Id;
The resulting string is 'W. Europe Standard Time' (hello from Germany btw.)

How can I get 'Europe/Berlin' out of this string? The Windows time zone id is ambiguous, so 'W. Europe Standard Time' contains 'Europe/Berlin', 'Europe/Amsterdam', 'Europe/Vienna' and some more. I didn't find anything inside your library which can handle Windows time zone identifiers. Did I miss something or is it planned to add this functionality in the future?

Thank you for all the work you did to put this API together. The tz database seemed so daunting but your APIs seem to make it very simple to use.

Anyway, my problem is that I want to have a list of timezones on my site so that a user can customize their timezone by selecting one from the list. The problem is that GetZoneNames() returns 452 timezones. That list is more than a little intimidating. I'm still very new to how timezones work so don't flame me for asking, but is there a way to only show unique names or anything to get that list smaller? On Flickr.com for example they have a list of 75 timezones to pick from. How would I get a list like that? Or is it just not possible with this database.

Thanks for the quick response. Your API looks really great, but we've decided to go another route on our project. We just discovered that as of version 3.5, .NET includes a TimeZoneInfo library that is very easy to use and meets all of our requirements.

I have had a look at this library and it seems to work for time zone conversions but the ConvertToLocal expects a UTC DateTime but the GetUtcOffset that is called with in the convert method expects a local time.

Therefore if you have dates that cross over the DS period the offset is not calculated correctly.
E.g.

I have discovered a small error when converting from UTC to local time zone. It only happens when the time zone has a negative offset and a minute portion. I discovered this while doing some testing on conversions for St. John's, Newfoundland, Canada which has GMT -3:30 although there are other zones effected as well.

The problem is in the Database.ConvertToTimeSpan function which parses a time string and converts to a TimeSpan object. When the hour portion is negative the minutes and seconds remain positive and end up getting subtracted from the hours. It can be corrected as follows:

min = Convert.ToInt32(array[1]) * Math.Sign(hour);

Otherwise, I have been using your library without incident. It has made my life a lot easier and more consistent than using MS time zones! Thanks!

I have one thing against using the Olsen tz database and that is, in the words off the web reference you gave "The data are by no means authoritative". So, what does constitute an 'authoritative' source ? (thats a general question/muse, I dont expect an answer)

In our 'shop', we have Microsoft Win XP/2003 etc boxes, Sun Solaris boxes - I know that for every change to DST into for example, our support crews patch every server and workstation (the workstations are managed by Novell Zenworks so thats not too hard).. so my point is, is it safe to use the Microsoft Registry (database) for the timezones ? (I dont know if you can access the Sun 'data') .. if you :-

can access the Microsoft Registry
and it provides the info you need (DST etc)
and its kept up to date

is that not enough ?

just a general thought, Im not knocking your work, just thinking of alternatives for the reference info ..

The Olson database seemed like the best source at the time ... and still does now although I am happy to be re-educated

can access the Microsoft Registry
and it provides the info you need (DST etc)
and its kept up to date

is that not enough ?

A couple of things here:
1. I am currently writing a web app on a hosted server so access to the Microsoft registry is not an option for me.
2. I don't think that it DOES provide me with all the information that I need

I need to be able to book a meeting 8 months from now and invite multiple participants around the world.
Each participant will see the meeting in their local time (which will probably not be the local time of the current server).

If you know the API's to get this data out of a MS Server I would love to know it.

I need to be able to book a meeting 8 months from now and invite multiple participants around the world.
Each participant will see the meeting in their local time (which will probably not be the local time of the current server).

yes, I went to your ?work site (must be if you're the CTO) and was impressed with what you do .. and understand your challenges.

if it were me I'd probably start with a copy of the Olsen tz database, and derive an automated procedure for updating it from a number of possible sources - a Microsoft OS based pc, (does NIST have anything?), Sun etc .. my version to me would then be the authoritative source ..

we had a process go ape last week - it uses the java joda kit I beleive with its own tz database .. basically, transactions performed realtime in say Qld are logged - by the server in Syd time... the reconciliation trace coming from the bank comes back in the local time of the remote QLD devices - ergo we need to 'normalise the times' so they match the central server

because they didnt edit the java tz database to reflect the DST extension of a week, a weeks worth of transactions wouldnt reconcile