C# – How should I deal with Time Zones in a .NET WCF application

cnettimewcfwindows-registry

Our company runs a SaaS application where users log in from across the world (although mostly in the US). We store all our time relevant information as UTC, but we need to display times using local time. The application is web based, and we would like to "auto-detect" the user's Time Zone by using javascript to determine their UTC offsets during various times of the year. The user's offset info would be passed to our server in their first request and the server will look up all the Time Zones that it knows about and see which valid time zones match.

I'd like to use the built in TimeZoneInfo object, but I understand that

TimeZoneInfo.GetSystemTimeZones();

relies on the server's registry settings. We currently have 18 load balanced web servers that host our WCF service layer, and I believe our TechOps team is vigilant in making sure that all servers are patched with the same service pack at all times.

I also need to pay special attention to the various US Time Zones, specifically Pacific, Mountain, Central and Eastern. Can I assume that the string based Id field will not change anytime soon? For example, if I call

TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time")

I want the appropriate TimeZoneInfo object to be returned.

So a few questions:

  • What is the best way to deal with time zones, especially when it comes to the changing rules (US time zone rules changed in 2006) and determining offsets. Should I be trying something else? Keep in mind that the product team doesn't want the user to have to select their time zone and they are fine with time zones being inaccurately reported under certain conditions (e.g. if the user is in Mexico, it is ok to be reported as "Pacific Standard Time" instead of the more accurate "Pacific Standard Time (Mexico)".
  • If I assume that all of our load balanced web servers are always running the same OS version and patch level, can I assume that I will get consistent results?
  • Are there any other things I need to consider?

Best Answer

I think you're on the right track with using the built in TimeZoneInfo class. The ID should never change, but the name will (I learned that lesson the hard way when several changed between xp and vista). I have used a virtually identical approach (UTC only at the service and db layers, local time on the web server & client) and it worked just fine.

One thing I suggest is to wrap the various TimeZoneInfo methods you intend to use with an interface ITimeZoneConverter or something of that nature, that way if you need to change your implementation later, it should be easier to do.

Random Annoyance: The .Net TimeZoneInfo class can't give you an abbreviation given a timezone. IE: No "EST" for "Eastern Standard Time", so if you need that, plan on having a lookup into some sort of resource file or table for that.

Javascript won't actually be able to tell you the timezone, just the timezone offset from UTC. It's a subtle difference, and in your case it sounds like it won't matter, but it's something to keep in mind when looking at what timezones get assigned to your users.

I have seen some JS libraries such as this one which attempt to guess the timezone on the client side based on offset and most populated timezones. It is an interesting approach, but I don't know how well it would work in production.

Finally, one thing that bit me in the past was that JSON doesn't actually specify anything about how to format datetimes. (related reading) If you're doing a lot of ajax/async requests and intend to convert back and forth between utc & local times, this can be painful. Make sure you write some good common parsing/offsetting functions and make sure everyone on your team is aware of them and doesn't re-invent the wheel every time when dealing with these issues.

Related Topic