5

In NodaTime, how do you find the long form name of a timezone given the tz timezone id?

For example, if I supply "America/Los_Angeles", I should get "Pacific Standard Time" back.

govin
  • 6,445
  • 5
  • 43
  • 56
  • Possible duplicate: http://stackoverflow.com/questions/19252700/converting-between-time-zones-with-noda-time – Mike Aug 01 '14 at 17:57
  • 1
    Don't think its a duplicate. I don't want to convert between. I just want the friendly/long form name back – govin Aug 01 '14 at 17:59
  • Just to be whiny: shouldn't "America/Los_Angeles" return "Pacific Time" (PT) instead of "Pacific Standard Time" (PST)? Los Angeles is only on PST during the winter, and on "Pacific Daylight Time" (PDT) in the summer. PT is equal to PST in the winter and PDT in the summer, and would be a better option, or something like "Pacific Standard|Daylight Time" would be more accurate. –  Nov 03 '15 at 13:48

3 Answers3

8

The information you need to produce the "long form" of a time zone name isn't in Noda Time, but it can be found in the CLDR.

I've recently put together a library called simply "Time Zone Names", that embeds the CLDR time zone names. You can use these with the IANA (TZDB) identifiers that are used by Noda Time time zones.

Simply pass the time zone and language, and it will provide the appropriate generic name, standard name, and daylight name. You can use Noda Time to decide which form is appropriate to display.

var names = TimeZoneNames.GetNamesForTimeZone("America/Los_Angeles", "en-US");

Assert.Equal("Pacific Time", names.Generic);
Assert.Equal("Pacific Standard Time", names.Standard);
Assert.Equal("Pacific Daylight Time", names.Daylight);

For the language, you can pass either a two digit code like "en", or you can pass a fully regionalized version such as "en-US". This aligns with CultureInfo names, so you can pass CultureInfo.CurrentUICulture.Name if you like.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • CLDR seems to have a few errors. It refers to "MST7MDT" as "Mountain Standard Time", but the actual name is just "Mountain Time". "MST", a different time zone, is properly called "Mountain Standard Time". The difference is not purely academic: during the US summer, Arizona observes "Mountain Standard Time", where as New Mexico observes regular "Mountain Time", which is an hour ahead, because "Mountain Time" means "Mountain Daylight Time" in the summer. –  Nov 03 '15 at 04:13
  • @barrycarter - Yes, which is why there is a difference between `names.Generic` and `names.Standard` in the output. I checked and `MST7MDT` works as you describe it. You can see [in the cldr](http://unicode.org/repos/cldr/trunk/common/supplemental/metaZones.xml) that it is in the `America_Mountain` metazone. Anyway, if you have further concerns with the CLDR, please send them to the CLDR. If you have concerns with my library, [log them at the project site](https://github.com/mj1856/TimeZoneNames/issues). Thanks. – Matt Johnson-Pint Nov 03 '15 at 05:32
  • Thanks, Matt, and I have done so. I was actually referring to the "windowsZones.xml" file, which is the only one that appears to have full timezone names? –  Nov 03 '15 at 13:11
  • 1
    No, the names are in the locale-specific files in /common/main, such as /common/main/en.xml. Don't use the Windows IDs as names. – Matt Johnson-Pint Nov 03 '15 at 15:17
1

TZDB itself doesn't hold descriptions for timezones: the timezone with ID America/Los_Angeles simply holds transitions with names such as "PDT" and "PST". So from that point of view, the data simply isn't there.

That said, you can get the Windows timezone IDs that map to a given TZDB zone (originally from the CLDR windowsZones.xml data), and Windows generally does use names like "Pacific Standard Time" for its zone IDs.

e.g.

var source = TzdbDateTimeZoneSource.Default;
var windowsIds = (from item in source.WindowsMapping.PrimaryMapping
    where item.Value == "America/Los_Angeles"
    select item.Key).ToList();

However, there are some caveats with this approach:

  • As shown above, there may be any number of Windows zone IDs that map to a given TZDB zone. In the current data, this is always zero or one (Europe/Vienna being an example of a TZDB zone that no Windows zone ID uses), but there's no reason in theory that you couldn't find two or more Windows zone IDs mapping to the same TZDB zone.
  • Some of the Windows zone IDs aren't particularly great: for example, Europe/London is mapped from a Windows zone called "GMT Standard Time", which isn't a great string to show to a user.

However, for what you're doing, this might be acceptable.

Malcolm Rowe
  • 747
  • 3
  • 14
0

Short answer: https://github.com/barrycarter/bcapps/blob/master/ASTRO/tz2name.txt

Long answer: As others have noted, you can use CLDR's common/supplemental/metaZones.xml file to map timezones to regions. For example:

                    <timezone type="America/Barbados">
                            <usesMetazone mzone="Atlantic"/>
                    </timezone>

maps the timezone "America/Barbados" to the region "Atlantic".

You can then use common/main/en.xml to convert the region to a timezone name. For example:

                    <metazone type="Atlantic">
                            <long>
                                    <generic>Atlantic Time</generic>
                                    <standard>Atlantic Standard Time</standard>
                                    <daylight>Atlantic Daylight Time</daylight>
                            </long>
                            <short>
                                    <generic>AT</generic>
                                    <standard>AST</standard>
                                    <daylight>ADT</daylight>
                            </short>
                    </metazone>

tells us the names of the timezones (long and short forms) used in the "Atlantic" region.

This is pretty much a repeat of the other answers, but with direct references to files in question.