0

I am looking into mapping a location such as an adress to a Windows TimeZone format. For instance if the address contains the Copenhagen city, then the service should map it to (UTC+01:00) Brussels, Copenhagen, Madrid, Paris.

If the address contains a city close to Vienna then it should map it to (UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna.

I have looked into Google's GeoCoding and TimeZone APIs, but it only gives me the name of the timezone like "Central European Time".

Oliver Nilsen
  • 1,017
  • 2
  • 12
  • 32

1 Answers1

1

This is a multi-step process:

  1. Determine the location's latitude and longitude coordinates.

    • You mentioned Google's geocoding API. That will do fine, and there are several others to choose from.
  2. Determine the time zone identifier from those coordinates using any of these methods.

    • In most cases, you'll receive an IANA time zone identifier, such as "Europe/Vienna". You mentioned the Google time zone API - which returns this value in the timeZoneId field (not timeZoneName).
  3. Use the IANA time zone identifier to obtain a .NET TimeZoneInfo object.

    • If you are running .NET on a non-Windows platform (Linux, OSX, etc.) you can obtain a TimeZoneInfo object directly from the IANA time zone identifier:

      // This will work on platforms that use IANA time zones natively
      TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("Europe/Vienna");
      
    • If you are running .NET on Windows, or want to write your application to run on any platform, then use my TimeZoneConverter library to retrieve the TimeZoneInfo object:

      // This will work on any platform
      TimeZoneInfo tzi = TZConvert.GetTimeZoneInfo("Europe/Vienna");
      

If you actually need a Windows time zone identifier, then TimeZoneConverter can do that as well:

string tz = TZConvert.IanaToWindows("Europe/Vienna");
//=> "W. Europe Standard Time"

Separately, if you want to get the actual string "(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna", then:

  • If on Windows, and the Windows OS locale is English, then you can just get .DisplayName from the TimeZoneInfo object.

  • In all other cases, you can skip step 3 above and just use my TimeZoneNames library, which has all display names for all languages:

    string displayName = TZNames.GetDisplayNameForTimeZone("Europe/Vienna", "en");
    

Also, you might consider using NodaTime instead of a TimeZoneInfo object.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • Thx Matt for the detailed answer. I am fully aware and have done steps 1-2 but description in step 3 is new to me. I will try to implement it as soon as possible and get back to this post. – Oliver Nilsen Jun 16 '20 at 19:29
  • HI Matt, I am still researching but so far this method "TimeZoneInfo tzi = TZConvert.GetTimeZoneInfo("Europe/Vienna")" is what works for me on my personal laptop, where Regional Settings is set to English. I have to see how it behaves when it runs in an Azure Function for .NET Core runtime. I am trying to get my head around all these terms, IANA, Windows TimeZone identifier, CLDR, POSIX, tz, NodaTime etc. – Oliver Nilsen Jun 21 '20 at 19:47
  • What do you *do* with `tzi` after you retrieve it? – Matt Johnson-Pint Jun 22 '20 at 16:12
  • Currently I just store it in a column i database. I have noticed that TZConvert.GetTimeZoneInfo("Central European Summer Time") cannot be found. I have updated my Win 10 and checked the list of timezone names in Windows Registry with tzutil /l, and this Central European Summer Time actually doesn't exist. But it is valid timezone name. – Oliver Nilsen Jun 30 '20 at 18:32
  • If I try to get the timezone name "Central European Summer Time" from NodaTime library it also cannot find this timezone: DateTimeZoneProviders.Tzdb["Central European Summer Time"] – Oliver Nilsen Jun 30 '20 at 18:42
  • That's because the string `"Central European Summer Time"` is not a valid Windows time zone ID. `tzutil /l` returns all *Display Names* (localized for the OS's current language) and their corresponding IDs. The IDs are never localized, and they don't change for daylight/summer time. In other words, the ID `"Central European Standard Time"` identifies the time zone, regardless of whether standard or summer time is in effect in that time zone. – Matt Johnson-Pint Jul 01 '20 at 17:07
  • Also, the Noda Time TZDB provider is for IANA time zones (like `Europe/Vienna`). You might want to read through [the timezone tag wiki](https://stackoverflow.com/tags/timezone/info) if you haven't yet. In particular, note the section titled "Time Zone Databases", and pay attention to the details about inconsistencies with naming conventions of Windows time zone identifiers. – Matt Johnson-Pint Jul 01 '20 at 17:08
  • Hi Mat, it works for me when I provide the TimeZone ID from Google TimeZone API result and not the TimeZone Name. – Oliver Nilsen Jul 03 '20 at 16:42
  • One more time thanks so much for providing a solution and explaining things in detail. By far the most honest help I have gotten here on SO. I learned a lot about timezones. – Oliver Nilsen Jul 05 '20 at 12:50