Get timezone from DateTime

C#.NetDatetimeTimezone

C# Problem Overview


Does the .Net DateTime contain information about time zone where it was created?

I have a library parsing DateTime from a format that has "+zz" at the end, and while it parses correctly and adjusts a local time, I need to get what the specific time zone was from the DateTime object.

Is this possible at all? All I can see is DateTime.Kind, which specifies if time is local or UTC.

C# Solutions


Solution 1 - C#

DateTime itself contains no real timezone information. It may know if it's UTC or local, but not what local really means.

DateTimeOffset is somewhat better - that's basically a UTC time and an offset. However, that's still not really enough to determine the timezone, as many different timezones can have the same offset at any one point in time. This sounds like it may be good enough for you though, as all you've got to work with when parsing the date/time is the offset.

The support for time zones as of .NET 3.5 is a lot better than it was, but I'd really like to see a standard "ZonedDateTime" or something like that - a UTC time and an actual time zone. It's easy to build your own, but it would be nice to see it in the standard libraries.

EDIT: Nearly four years later, I'd now suggest using Noda Time which has a rather richer set of date/time types. I'm biased though, as the main author of Noda Time :)

Solution 2 - C#

No.

> A developer is responsible for keeping track of time-zone information associated with a DateTime value via some external mechanism.

A quote from an excellent article here. A must read for every .Net developer.

So my advice is to write a little wrapper class that suits your needs.

Solution 3 - C#

There is a public domain TimeZone library for .NET. Really useful. It will answer your needs.

Solving the general-case timezone problem is harder than you think.

Solution 4 - C#

You could use TimeZoneInfo class

The TimeZone class recognizes local time zone, and can convert times between Coordinated Universal Time (UTC) and local time. A TimeZoneInfo object can represent any time zone, and methods of the TimeZoneInfo class can be used to convert the time in one time zone to the corresponding time in any other time zone. The members of the TimeZoneInfo class support the following operations:

  1. Retrieving a time zone that is already defined by the operating system.

  2. Enumerating the time zones that are available on a system.

  3. Converting times between different time zones.

  4. Creating a new time zone that is not already defined by the operating system.

    Serializing a time zone for later retrieval.

Solution 5 - C#

From the API (http://msdn.microsoft.com/en-us/library/system.datetime_members(VS.71).aspx) it does not seem it can show the name of the time zone used.

Solution 6 - C#

DateTime does not know its timezone offset. There is no built-in method to return the offset or the timezone name (e.g. EAT, CEST, EST etc).

Like suggested by others, you can convert your date to UTC:

DateTime localtime = new DateTime.Now;
var utctime = localtime.ToUniversalTime();

and then only calculate the difference:

TimeSpan difference = localtime - utctime;

Also you may convert one time to another by using the DateTimeOffset:

DateTimeOffset targetTime = DateTimeOffset.Now.ToOffset(new TimeSpan(5, 30, 0));

But this is sort of lossy compression - the offset alone cannot tell you which time zone it is as two different countries may be in different time zones and have the same time only for part of the year (eg. South Africa and Europe). Also, be aware that summer daylight saving time may be introduced at different dates (EST vs CET - a 3-week difference).

You can get the name of your local system time zone using TimeZoneInfo class:

TimeZoneInfo localZone = TimeZoneInfo.Local;
localZone.IsDaylightSavingTime(localtime) ? localZone.DaylightName : localZone.StandardName

I agree with Gerrie Schenck, please read the article he suggested.

Solution 7 - C#

Generally the practice would be to pass data as a DateTime with a "timezone" of UTC and then pass a TimeZoneInfo object and when you are ready to display the data, you use the TimeZoneInfo object to convert the UTC DateTime.

The other option is to set the DateTime with the current timezone, and then make sure the "timezone" is unknown for the DateTime object, then make sure the DateTime is again passed with a TimeZoneInfo that indicates the TimeZone of the DateTime passed.

As others have indicated here, it would be nice if Microsoft got on top of this and created one nice object to do it all, but for now you have to deal with two objects.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondbkkView Question on Stackoverflow
Solution 1 - C#Jon SkeetView Answer on Stackoverflow
Solution 2 - C#Gerrie SchenckView Answer on Stackoverflow
Solution 3 - C#CheesoView Answer on Stackoverflow
Solution 4 - C#Shashank ShekharView Answer on Stackoverflow
Solution 5 - C#tehvanView Answer on Stackoverflow
Solution 6 - C#henryalligatorView Answer on Stackoverflow
Solution 7 - C#RobView Answer on Stackoverflow