As described in the timezone tag wiki, there are two different styles of time zones.
Those provided by Microsoft for use with Windows and the .Net TimeZoneInfo class (when running on Windows) are identified by a value such as "Eastern Standard Time".
Those provided by IANA in the TZDB, and used by the .NET TimeZoneInfo class when running on Linux or OSX, are identified by a value such as "America/New_York".
Many Internet-based APIs use the IANA time zones, but for numerous reasons one might need to convert this to a Windows time zone id, or vice-versa.
How can this be accomplished in .Net?
Current Status:
Starting with .NET 6, both forms of time zones are supported on any platform that has both time zone data and ICU installed, which is most installations of Windows, Linux, and MacOS. See Tobias's answer.
Original Answer:
The primary source of the data for conversion between Windows and IANA time zone identifiers is the windowsZones.xml file, distributed as part of the Unicode CLDR project. The latest dev version can be found here.
However, CLDR is released only twice annually. This, along with the periodic cadence of Windows updates, and the irregular updates of the IANA time zone database, makes it complicated to just use the CLDR data directly. Keep in mind that time zone changes themselves are made at the whim of the world's various governments, and not all changes are made with sufficient notice to make it into these release cycles before their respective effective dates.
There are a few other edge cases that need to be handled that are not covered strictly by the CLDR, and new ones pop up from time to time. Therefore, I've encapsulated the complexity of the solution into the TimeZoneConverter micro-library, which can be installed from Nuget.
Using this library is simple. Here are some examples of conversion:
string tz = TZConvert.IanaToWindows("America/New_York");
// Result: "Eastern Standard Time"
string tz = TZConvert.WindowsToIana("Eastern Standard Time");
// result: "America/New_York"
string tz = TZConvert.WindowsToIana("Eastern Standard Time", "CA");
// result: "America/Toronto"
There are more examples on the project site.
It's important to recognize that while an IANA time zone can be mapped to a single Windows time zone, the reverse is not true. A single Windows time zone might be mapped to more than one IANA time zone. This can be seen in the above examples, where Eastern Standard Time is mapped to both America/New_York, and to America/Toronto. TimeZoneConverter will deliver the one that CLDR marks with "001", known as the "golden zone", unless you specifically provide a country code and there's a match for a different zone in that country.
Note: This answer has evolved over the years, so comments below may or may not apply to the current revision. Review the edit history for details. Thanks.
Starting with .NET 6, it is finally possible to work with time zones in a cross-platform manner, so these manual workarounds are no longer needed.
The TimeZoneInfo.FindSystemTimeZoneById(string) method automatically accepts either Windows or IANA time zones on either platform and converts them if needed.
// Both of these will now work on any supported OS where ICU and time zone data are available.
TimeZoneInfo tzi1 = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");
TimeZoneInfo tzi2 = TimeZoneInfo.FindSystemTimeZoneById("Australia/Sydney");
Note that, as specified on the link, the .NET Core Alpine Linux-based Docker images do not have the necessary tzdata installed by default, so it must be installed in your Dockerfile for this to work correctly.
I know this is an old question, but I had a use case I though I would share here, since this is the most relevant post I found when searching. I was developing a .NET Core app using a docker linux container, but for deployment on a windows server. So I only needed my docker linux container to support the windows timezone names. I got this working without changing my application code by doing the following:
cp /usr/share/zoneinfo/America/Chicago "/usr/share/zoneinfo/Central Standard Time"
cp /usr/share/zoneinfo/America/New_York "/usr/share/zoneinfo/Eastern Standard Time"
cp /usr/share/zoneinfo/America/Denver "/usr/share/zoneinfo/Mountain Standard Time"
cp /usr/share/zoneinfo/America/Los_Angeles "/usr/share/zoneinfo/Pacific Standard Time"
Then, in my .NET code, the following worked without any modification: TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
Related
The client wants to see windows timezones, the ones at Time column here https://support.microsoft.com/en-us/help/973627/microsoft-time-zone-index-values except with UTC instead of GMT.
And also wants to see abbreviations. But I can't find any official windows timezones abbreviation list. What I find is IANA abbreviations.
We are goin to convert windows timezones to IANA timezones to work with time.
But the question is does IANA abbreviations=Windows timezones abbreviations?
If not where can I find the list of the rule for the windows abbreviations?
A few things:
The list you pointed at is not the official list of Microsoft Windows time zones. It is a copy of a very old static list from Windows Embedded 1.1., which has long been deprecated. There presently is no actively maintained list of all Windows time zones on a Microsoft web page.
To get a list of Windows time zones, call TZUTIL /L on the command line. It will return the ID and display name of each time zone installed on the system.
If you look at the CLDR zone mapping file, you'll see that many Windows zones map to more than one IANA zone. If you simply map the Windows zone to the 001 "golden zone", you may end up picking an IANA abbreviation that doesn't apply for the user. Thus, if you take the approach you described (converting to IANA and taking the IANA abbreviation), be sure to take the country code into consideration as well when doing the mapping.
Also:
There is no official single list of time zone abbreviations anywhere, because time zone abbreviations are not standardized. Many of the abbreviations we might use in English don't necessarily apply to non-English speakers, and many time zones don't have abbreviations at all.
Even in English, many time zone abbreviations are contradictory or ambiguous.
Some examples of problematic time zone abbreviations:
Does CST mean Central Standard Time, Cuba Standard Time, or China Standard Time?
Does IST mean India Standard Time, Israel Standard Time, or Ireland Standard Time?
Should Hawaii use HST or HAST?
Should HNE (Heure Normale de l'Est) be used instead of EST (Eastern Standard Time) in Quebec, Canada since its official language is French?
What is the time zone abbreviation of Minsk, Belarus? You might think MSK, but that's offensive to some because that abbreviation is also commonly used for Moscow, Russia. Belarus has one time zone for the whole country, and they don't speak English there. IANA gives the abbreviation as simply the numeric UTC offset +03 (since mid 2011).
Because of the above problems...
There is no official list of time zone abbreviations for Windows time zones. Windows doesn't use them.
You might find some time zone abbreviations listed in CLDR data, and exposed with various libraries and APIs, but they only sparsely populated in the data set. CLDR has not been reliably collecting or maintaining time zone abbreviations.
I'm wondering if anyone else is seeing an issue with specific time zone abbreviations in their Rails apps on Ubuntu 12.0.4 boxes with tzdata 2016j.
For Asia/Yerevan, Asia/Istanbul, and Asia/Baku I seem to be getting incorrect Time Zone abbreviations - Time.now.in_time_zone will display the time with zone abbreviations: +04, +03, +04 when running the app on Ubuntu 12.0.4, whereas on my Mac (OS X El Capitan), I'm seeing AMT, EET, and AZT respectively (looks like Istanbul is getting incorrect time zone there).
If you're on any other version of Ubuntu or tzdata, I'd also appreciate any insight into what time zone abbreviations you get for these zones. I'm still trying to figure out which part of the stack is causing the issue.
Also, if anyone has a workaround, I'd greatly appreciate any insight there as well.
The source data itself has been changed. Over the last several releases, the TZ maintainers have been removing abbreviations that were previously invented or otherwise unsubstantiated.
The fact of the matter is that the idea of a "time zone abbreviation" is not a universal concept. We'd like to think that everyone around the world uses them, but really they don't. And when they do, they do not necessarily mean the same things as we think they do, or are the chosen abbreviations used universally. For example, A person in Minsk might happen to use the same UTC offset as a person in Moscow, but Moscow's use of MSK is well-known. Applying it to Minsk could be taken as an insult. Indeed, the TZDB used to use MSK for "Minsk Time", until this recent set of changes started.
It gets even more complicated when you think about abbreviations in other langugages.
If you have documentation to show that an abbreviation is actually used by those who live in the place in question (i.e., do people in Baku actually say "AZT"), then please present your findings on the discussion mailing list at IANA.
If you're just trying to get back what you had before - you'll have to make a list of your own "invented" abbreviations and refer to that. The TZDB is clear that it no longer wants to be the source of misinformation.
The better option, IMHO, is just to avoid using time zone abbreviations at all.
I use "Moment.js" and it's addition "moment-timezone" in a Web application that supports several languages (english, german, french etc.).
So to improve the user experience I'd like to know if there already exists a localization file (like the one for Moment.js) that can change timezone names from english to the desired language or do I need to write it myself?
For instance: String "Europe/Vienna" would be in that case changed to "Europe/Wien"
A few things:
What you're looking for doesn't exist in moment or moment-time zone.
You shouldn't actually change to "Europe/Wien". The time zone strings are IANA time zone identifiers, and are always in English.
In general, IANA time zone identifiers aren't designed for human readability. Translation to human readable names like "Central European Time" in English, or "Mitteleuropäische Zeit" in German, is the responsibility of the CLDR project.
You can use the Globalize library to get access to CLDR data in JavaScript, however AFAIK they don't currently have support for time zone names. I've requested this here.
Even with an adequate translation of IANA time zone ID to localized time zone names, it can be difficult to use this data to build time zone picker controls. I've done this in .NET with my TimeZoneNames library (demo here), but not in pure JS. I've yet to see a simple solution to this in JavaScript yet. If I ever find one (or create one), I'll come back here and update this answer.
Other alternatives you might consider are to use a map-based time zone picker, such as this one, or this one, and others.
import moment from 'moment';
import 'moment/locale/fr';
moment.locale('fr')
Visit Here
I have users stored in the database and need to save a timezone to associate with the user so that I can use it to create events with AddThisEvent and to display other localized times.
Is the mapping from a timezone offset to the AddThisEvent zonecode arbitrary- or is he using some standard that I couldn't find?
The documentation in Step 2 describes the list of available values for the _zonecode.
These appear to be Microsoft Windows time zones, as mentioned in the timezone tag wiki.
However, the actual integers assigned to each "Zonecode" appear to be proprietary to AddThisEvent. It's likely that they are using TimeZoneInfo.GetSystemTimeZones in .NET, and assigning each entry to an integer.
Hopefully, they realize that this list is not necessarily fixed. Microsoft can provide updates which add entries to Windows when new time zones need to be created. For example, two new time zones are being added soon for the upcoming October 2014 Russian time zone changes. These would be added in the middle of the list, so the list would no longer be sequential. If they are just using an index value of the array returned, they'll be surprised when the changes cause everything to shift forward.
(Note - I have no special knowledge of how AddThisEvent is actually planning to handle updates. I am just speculating.)
In general - integers are not good time zone identifiers.
So what should I do then?
Map each of the proprietary entries back to the Windows time zone they belong to. Then, if necessary, map them to the standard IANA TZ identifier used by PHP, Python, Java, etc. You can use the CLDR mappings to determine an appropriate TZ identifier to use for each Windows time zone.
It's a shame you'll have to jump through so many hoops, but in the end, you'll be able to figure out the appropriate integer to use with AddThisEvent for each user.
It looks like AddThisEvent has already updated their timezone handling. However, if people are still using the older library and are running into this problem, one solution is to convert the datetime to UTC before passing it to AddThisEvent. Then you can use the _zonecode 35 (UTC). Calendar options like Google, Outlook, etc should be able to convert from UTC to the user's timezone appropriately.
I came across a mapping file for timezone strings from glibc to uclibc. It looks like this:
Africa/Abidjan=GMT0
Africa/Accra=GMT0
Africa/Addis Ababa=EAT-3
Africa/Algiers=CET-1
...
This file is quite old (4 years), and several new TimeZones have been added on glibc. However, I could not find the latest mapping file. The mapping file has 451 entries, where as the total timezone strings supported these days is over 900. Is there an updated mapping file for the same?
From the data you provided, the left side appears to be an IANA/Olson time zone identifier. You can see a rough list of these zones and their offsets on Wikipedia.
The right side appears to be a time zone abbreviation and the standard offset for the zone, with its sign inverted. This might be a POSIX style time zone string. I can't tell since you only provided a small sampling.
You can read more about both of these in the timezone tag wiki. Be sure to read about the limitations of POSIX time zones.
Some searching found this thread where they discuss that uclibc only supports POSIX time zones. If you're using buildroot, you could see if the "tzdata" package will work for you, but I'm not sure if it will or not. If it does, you would use it the same way that glibc does, with the TZ variable setting (see the last option at the bottom of the page).
As far as mapping IANA to POSIX zones - any list you have is going to be limited to the current time zone rules, and then still won't cover necessarily everything. Only the IANA zones are comprehensive. It would also be a one-way mapping. You could not go the other direction. I searched, but did not find a direct source for this mapping. If you find one, please let me know.