Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET TimeZoneInfo from Olson time zone

Tags:

timezone

c#

.net

How can I convert the following into a System.TimeZone or System.TimeZoneInfo?

{   "timeZone": "America/Los_Angeles",    "currentOffsetMs": -25200000 } 

This is data I'm getting back from a 3rd party web service.

I'm assuming the offset is the difference from UTC, and I'm told that the "America/Los_Angeles" is an Olson time zone. Java has no problems parsing this into a Java TimeZone, but I need to parse this into a C# TimeZoneInfo object.

like image 509
Judah Gabriel Himango Avatar asked May 13 '11 18:05

Judah Gabriel Himango


People also ask

How do I get the TimeZone from DateTime?

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.

How do I get Eastern time in C#?

For example, if we are going to use Eastern Standard Time, then we can use the code given below. DateTime dateTime_Eastern = TimeZoneInfo. ConvertTimeFromUtc(DateTime. UtcNow, Eastern_Standard_Time);


2 Answers

This Unicode.org page has a "Olson time zone to Win32 time zone" table. From there, I created a nice little C# helper function to map from Olson time zone string into a .NET TimeZoneInfo:

/// <summary> /// Converts an Olson time zone ID to a Windows time zone ID. /// </summary> /// <param name="olsonTimeZoneId">An Olson time zone ID. See http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html. </param> /// <returns> /// The TimeZoneInfo corresponding to the Olson time zone ID,  /// or null if you passed in an invalid Olson time zone ID. /// </returns> /// <remarks> /// See http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html /// </remarks> public static TimeZoneInfo OlsonTimeZoneToTimeZoneInfo(string olsonTimeZoneId) {     var olsonWindowsTimes = new Dictionary<string, string>()     {         { "Africa/Bangui", "W. Central Africa Standard Time" },         { "Africa/Cairo", "Egypt Standard Time" },         { "Africa/Casablanca", "Morocco Standard Time" },         { "Africa/Harare", "South Africa Standard Time" },         { "Africa/Johannesburg", "South Africa Standard Time" },         { "Africa/Lagos", "W. Central Africa Standard Time" },         { "Africa/Monrovia", "Greenwich Standard Time" },         { "Africa/Nairobi", "E. Africa Standard Time" },         { "Africa/Windhoek", "Namibia Standard Time" },         { "America/Anchorage", "Alaskan Standard Time" },         { "America/Argentina/San_Juan", "Argentina Standard Time" },         { "America/Asuncion", "Paraguay Standard Time" },         { "America/Bahia", "Bahia Standard Time" },         { "America/Bogota", "SA Pacific Standard Time" },         { "America/Buenos_Aires", "Argentina Standard Time" },         { "America/Caracas", "Venezuela Standard Time" },         { "America/Cayenne", "SA Eastern Standard Time" },         { "America/Chicago", "Central Standard Time" },         { "America/Chihuahua", "Mountain Standard Time (Mexico)" },         { "America/Cuiaba", "Central Brazilian Standard Time" },         { "America/Denver", "Mountain Standard Time" },         { "America/Fortaleza", "SA Eastern Standard Time" },         { "America/Godthab", "Greenland Standard Time" },         { "America/Guatemala", "Central America Standard Time" },         { "America/Halifax", "Atlantic Standard Time" },         { "America/Indianapolis", "US Eastern Standard Time" },         { "America/Indiana/Indianapolis", "US Eastern Standard Time" },         { "America/La_Paz", "SA Western Standard Time" },         { "America/Los_Angeles", "Pacific Standard Time" },         { "America/Mexico_City", "Mexico Standard Time" },         { "America/Montevideo", "Montevideo Standard Time" },         { "America/New_York", "Eastern Standard Time" },         { "America/Noronha", "UTC-02" },         { "America/Phoenix", "US Mountain Standard Time" },         { "America/Regina", "Canada Central Standard Time" },         { "America/Santa_Isabel", "Pacific Standard Time (Mexico)" },         { "America/Santiago", "Pacific SA Standard Time" },         { "America/Sao_Paulo", "E. South America Standard Time" },         { "America/St_Johns", "Newfoundland Standard Time" },         { "America/Tijuana", "Pacific Standard Time" },         { "Antarctica/McMurdo", "New Zealand Standard Time" },         { "Atlantic/South_Georgia", "UTC-02" },         { "Asia/Almaty", "Central Asia Standard Time" },         { "Asia/Amman", "Jordan Standard Time" },         { "Asia/Baghdad", "Arabic Standard Time" },         { "Asia/Baku", "Azerbaijan Standard Time" },         { "Asia/Bangkok", "SE Asia Standard Time" },         { "Asia/Beirut", "Middle East Standard Time" },         { "Asia/Calcutta", "India Standard Time" },         { "Asia/Colombo", "Sri Lanka Standard Time" },         { "Asia/Damascus", "Syria Standard Time" },         { "Asia/Dhaka", "Bangladesh Standard Time" },         { "Asia/Dubai", "Arabian Standard Time" },         { "Asia/Irkutsk", "North Asia East Standard Time" },         { "Asia/Jerusalem", "Israel Standard Time" },         { "Asia/Kabul", "Afghanistan Standard Time" },         { "Asia/Kamchatka", "Kamchatka Standard Time" },         { "Asia/Karachi", "Pakistan Standard Time" },         { "Asia/Katmandu", "Nepal Standard Time" },         { "Asia/Kolkata", "India Standard Time" },         { "Asia/Krasnoyarsk", "North Asia Standard Time" },         { "Asia/Kuala_Lumpur", "Singapore Standard Time" },         { "Asia/Kuwait", "Arab Standard Time" },         { "Asia/Magadan", "Magadan Standard Time" },         { "Asia/Muscat", "Arabian Standard Time" },         { "Asia/Novosibirsk", "N. Central Asia Standard Time" },         { "Asia/Oral", "West Asia Standard Time" },         { "Asia/Rangoon", "Myanmar Standard Time" },         { "Asia/Riyadh", "Arab Standard Time" },         { "Asia/Seoul", "Korea Standard Time" },         { "Asia/Shanghai", "China Standard Time" },         { "Asia/Singapore", "Singapore Standard Time" },         { "Asia/Taipei", "Taipei Standard Time" },         { "Asia/Tashkent", "West Asia Standard Time" },         { "Asia/Tbilisi", "Georgian Standard Time" },         { "Asia/Tehran", "Iran Standard Time" },         { "Asia/Tokyo", "Tokyo Standard Time" },         { "Asia/Ulaanbaatar", "Ulaanbaatar Standard Time" },         { "Asia/Vladivostok", "Vladivostok Standard Time" },         { "Asia/Yakutsk", "Yakutsk Standard Time" },         { "Asia/Yekaterinburg", "Ekaterinburg Standard Time" },         { "Asia/Yerevan", "Armenian Standard Time" },         { "Atlantic/Azores", "Azores Standard Time" },         { "Atlantic/Cape_Verde", "Cape Verde Standard Time" },         { "Atlantic/Reykjavik", "Greenwich Standard Time" },         { "Australia/Adelaide", "Cen. Australia Standard Time" },         { "Australia/Brisbane", "E. Australia Standard Time" },         { "Australia/Darwin", "AUS Central Standard Time" },         { "Australia/Hobart", "Tasmania Standard Time" },         { "Australia/Perth", "W. Australia Standard Time" },         { "Australia/Sydney", "AUS Eastern Standard Time" },         { "Etc/GMT", "UTC" },         { "Etc/GMT+11", "UTC-11" },         { "Etc/GMT+12", "Dateline Standard Time" },         { "Etc/GMT+2", "UTC-02" },         { "Etc/GMT-12", "UTC+12" },         { "Europe/Amsterdam", "W. Europe Standard Time" },         { "Europe/Athens", "GTB Standard Time" },         { "Europe/Belgrade", "Central Europe Standard Time" },         { "Europe/Berlin", "W. Europe Standard Time" },         { "Europe/Brussels", "Romance Standard Time" },         { "Europe/Budapest", "Central Europe Standard Time" },         { "Europe/Dublin", "GMT Standard Time" },         { "Europe/Helsinki", "FLE Standard Time" },         { "Europe/Istanbul", "GTB Standard Time" },         { "Europe/Kiev", "FLE Standard Time" },         { "Europe/London", "GMT Standard Time" },         { "Europe/Minsk", "E. Europe Standard Time" },         { "Europe/Moscow", "Russian Standard Time" },         { "Europe/Paris", "Romance Standard Time" },         { "Europe/Sarajevo", "Central European Standard Time" },         { "Europe/Warsaw", "Central European Standard Time" },         { "Indian/Mauritius", "Mauritius Standard Time" },         { "Pacific/Apia", "Samoa Standard Time" },         { "Pacific/Auckland", "New Zealand Standard Time" },         { "Pacific/Fiji", "Fiji Standard Time" },         { "Pacific/Guadalcanal", "Central Pacific Standard Time" },         { "Pacific/Guam", "West Pacific Standard Time" },         { "Pacific/Honolulu", "Hawaiian Standard Time" },         { "Pacific/Pago_Pago", "UTC-11" },         { "Pacific/Port_Moresby", "West Pacific Standard Time" },         { "Pacific/Tongatapu", "Tonga Standard Time" }     };      var windowsTimeZoneId = default(string);     var windowsTimeZone = default(TimeZoneInfo);     if (olsonWindowsTimes.TryGetValue(olsonTimeZoneId, out windowsTimeZoneId))     {         try { windowsTimeZone = TimeZoneInfo.FindSystemTimeZoneById(windowsTimeZoneId); }         catch (TimeZoneNotFoundException) { }         catch (InvalidTimeZoneException) { }     }     return windowsTimeZone; } 
like image 156
Judah Gabriel Himango Avatar answered Oct 15 '22 20:10

Judah Gabriel Himango


Here is a reverse mapping (tzdb -> windows) function using NodaTime:

using NodaTime; using NodaTime.TimeZones;  ...  public TimeZoneInfo GetTimeZoneInfoForTzdbId(string tzdbId) {   var mappings = TzdbDateTimeZoneSource.Default.WindowsMapping.MapZones;   var map = mappings.FirstOrDefault(x =>       x.TzdbIds.Any(z => z.Equals(tzdbId, StringComparison.OrdinalIgnoreCase)));   return map == null ? null : TimeZoneInfo.FindSystemTimeZoneById(map.WindowsId); } 

Note that it is possible for there to be more than one mapping (in which case this just uses the first one found), or no mapping at all (where this returns null).

In most commonly used time zones, this should work well enough. But the better solution would be to skip using TimeZoneInfo at all, and just use NodaTime throughout the application, directly with the TZDB zone you have.

See also: How to translate between Windows and IANA time zones?

like image 27
Matt Johnson-Pint Avatar answered Oct 15 '22 21:10

Matt Johnson-Pint