TimeZoneNames
Provides a complete source of localized time zone names.
Install / Use
/learn @mattjohnsonpint/TimeZoneNamesREADME
TimeZoneNames 
A simple library that provides localized time zone names using CLDR and TZDB sources.
Why? Because .NET's usual time zone display names are not localized properly, and are often wrong or unsuitable for various scenarios. Read this blog post for more details.
Note that if you are running .NET 6+ on Linux or macOS, the built-in names now stem from ICU and thus this library is no longer needed. See the .NET blog post for more details.
NOTE: Methods for retrieving localized time zone abbreviations have been deprecated, as the source data for abbreviations is generally unreliable.
Nuget Installation
PM> Install-Package TimeZoneNames
As of version 7.0.0, TimeZoneConverter works with all of the following:
- .NET 6 or greater
- .NET Core 2.0 or greater
- .NET Framework 4.6.2 and greater
Note that .NET Framework versions less than 4.6.2 are no longer supported.
Usage
First, import the TimeZoneNames namespace:
using TimeZoneNames;
All functionality is provided as static methods from the TZNames class.
Methods for localizing a single time zone
GetNamesForTimeZone
Look up the localized names for a specific time zone:
var names = TZNames.GetNamesForTimeZone("America/Los_Angeles", "en-US");
names.Generic == "Pacific Time"
names.Standard == "Pacific Standard Time"
names.Daylight == "Pacific Daylight Time"
var names = TZNames.GetNamesForTimeZone("America/Los_Angeles", "fr-CA");
names.Generic == "heure du Pacifique"
names.Standard == "heure normale du Pacifique"
names.Daylight == "heure avancée du Pacifique"
You can pass a Windows time zone id instead, if you like:
var names = TZNames.GetNamesForTimeZone("Romance Standard Time", "en-GB");
names.Generic == "Central European Time"
names.Standard == "Central European Standard Time"
names.Daylight == "Central European Summer Time"
Methods for listing time zones
GetDisplayNames
Gets a dictionary of string/string pairs of time zones, where the key is a time zone identifier, and the value is the localized name of the time zone, as given by the Windows language pack for the specified language and locale.
This is useful because the values returned by TimeZoneInfo.DisplayName are only localized by the
operating system's language, whereas TZNames.GetDisplayNames will work with any supported language.
var displayNames = TZNames.GetDisplayNames("fr-CA");
Output
Key | Value -------------------------------|-------------------------- Dateline Standard Time | (UTC-12:00) Ligne de date internationale (Ouest) UTC-11 | (UTC-11:00) Temps universel coordonné-11 Aleutian Standard Time | (UTC-10:00) Îles Aléoutiennes Hawaiian Standard Time | (UTC-10:00) Hawaii Marquesas Standard Time | (UTC-09:30) Îles Marquises Alaskan Standard Time | (UTC-09:00) Alaska UTC-09 | (UTC-09:00) Temps universel coordonné-09 Pacific Standard Time (Mexico) | (UTC-08:00) Basse Californie UTC-08 | (UTC-08:00) Temps universel coordonné-08 Pacific Standard Time | (UTC-08:00) Pacifique (É.-U. et Canada) ... | ...
Optionally, you can pass true as a second parameter to return IANA time zone IDs as the keys,
though the list will still be limited to valid Windows time zones. When doing so, if there is a
country code in the locale (eg. the CA in fr-CA) that code will be used as the territory code
in the Windows to IANA mapping.
GetTimeZonesForCountry
Gets a list of time zone names for a specific country, suitable for user time zone selection.
Returns a dictionary whose key is the IANA time zone identifier, and whose value is the localized generic time zone name. When more than one entry in the result set shares the same name, then a localized city name is appended in parenthesis to disambiguate. (This is usually due to historical differences.)
var zones = TZNames.GetTimeZonesForCountry("BR", "pt-BR");
Output
Key | Value --------------------------|-------------------------- America/Eirunepe | Horário do Acre (Eirunepé) America/Rio_Branco | Horário do Acre (Rio Branco) America/Porto_Velho | Horário do Amazonas (Porto Velho) America/Boa_Vista | Horário do Amazonas (Boa Vista) America/Manaus | Horário do Amazonas (Manaus) America/Campo_Grande | Horário do Amazonas (Campo Grande) America/Cuiaba | Horário do Amazonas (Cuiabá) America/Belem | Horário de Brasília (Belém) America/Fortaleza | Horário de Brasília (Fortaleza) America/Recife | Horário de Brasília (Recife) America/Araguaina | Horário de Brasília (Araguaína) America/Maceio | Horário de Brasília (Maceió) America/Bahia | Horário de Brasília (Bahia) America/Santarem | Horário de Brasília (Santarém) America/Sao_Paulo | Horário de Brasília (São Paulo) America/Noronha | Horário de Fernando de Noronha
Many scenarios don't require all time zones, so you can specify a threshold
date as an optional parameter:
var zones = TZNames.GetTimeZonesForCountry("BR", "pt-BR", new DateTime(2010, 1, 1));
Output
Key | Value --------------------------|-------------------------- America/Rio_Branco | Horário do Acre America/Manaus | Horário do Amazonas (Manaus) America/Cuiaba | Horário do Amazonas (Cuiabá) America/Fortaleza | Horário de Brasília (Fortaleza) America/Araguaina | Horário de Brasília (Araguaína) America/Bahia | Horário de Brasília (Bahia) America/Sao_Paulo | Horário de Brasília (São Paulo) America/Noronha | Horário de Fernando de Noronha
If you are not concerned with historical time zone differences at all, then
pass DateTimeOffset.UtcNow to return only time zones that differ in the future.
var zones = TZNames.GetTimeZonesForCountry("BR", "pt-BR", DateTimeOffset.UtcNow);
Output
Key | Value --------------------------|-------------------------- America/Rio_Branco | Horário do Acre America/Manaus | Horário do Amazonas (Manaus) America/Cuiaba | Horário do Amazonas (Cuiabá) America/Bahia | Horário de Brasília (Bahia) America/Sao_Paulo | Horário de Brasília (São Paulo) America/Noronha | Horário de Fernando de Noronha
GetTimeZoneIdsForCountry
Get a list of time zone identifiers for a specific country. Similar to the
GetTimeZonesForCountry method, but without localized names.
string[] zones = TZNames.GetTimeZoneIdsForCountry("AU");
Output
Australia/Perth
Australia/Eucla
Australia/Darwin
Australia/Broken_Hill
Australia/Adelaide
Australia/Brisbane
Australia/Lindeman
Australia/Hobart
Australia/Currie
Australia/Melbourne
Australia/Sydney
Australia/Lord_Howe
Antarctica/Macquarie
Like the GetTimeZonesForCountry method, an optional threshold parameter is
supported for limiting the list to those zones that vary only after a specific
date.
string[] zones = TZNames.GetTimeZoneIdsForCountry("AU", DateTimeOffset.Now);
Output
Australia/Perth
Australia/Eucla
Australia/Darwin
Australia/Adelaide
Australia/Brisbane
Australia/Sydney
Australia/Lord_Howe
Antarctica/Macquarie
GetFixedTimeZoneIds
Gets a list of time zone IDs that represent fixed offset from UTC, including UTC itself.
Note that time zones of the form Etc/GMT[+/-]n use an inverted sign from the usual
conventions.
TODO: Add examples for this method.
GetFixedTimeZoneNames
Gets the same list of zones as GetFixedTimeZoneIds, but includes localized names.
TODO: Add examples for this method.
GetFixedTimeZoneAbbreviations
Gets the same list of zones as GetFixedTimeZoneIds, but includes abbreviations.
TODO: Add examples for this method.
Additional supporting methods
GetDisplayNameForTimeZone
string displayName = TZNames.GetDisplayNameForTimeZone("America/Vancouver", "fr");
// => "(UTC-08:00) Pacifique (É.-U. et Canada)"
string displayName = TZNames.GetDisplayNameForTimeZone("India Standard Time", "zh-CN");
// => "(UTC+05:30) 钦奈,加尔各答,孟买,新德里"
GetCountryNames
Gets a localized list of country names, suitable for selecting a country before selecting a time zone in a two-dropdown time zone selection control.
var countries = TZNames.GetCountryNames("en-GB");
Output
Key | Value ------|-------------------------- AF | Afghanistan AX | Åland Islands AL | Albania .. | ... YE | Yemen ZM | Zambia ZW | Zimbabwe
GetLanguageCodes
Gets a list of all language codes supported by this library. Useful for testing and validation.
var languages = TZNames.GetLanguageCodes();
Output
af
agq
ak
am
ar
ar_ae
...
zgh
zh
zh_hans_sg
zh_hant
zh_hant_hk
zu
Acknowledgements
Many thanks to Tom Kludy, who helped figure out how to extract localized display names from Windows language packs.
This library uses output from his TimeZoneWindowsResourceExtractor
to enable the GetDisplayNames and GetDisplayNameForTimeZone methods.
