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.
Related
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
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")
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.
I've searched and found a couple of online web services that do this, but I was wondering it there's a database in the public domain which gives a list of latitudes and longitudes for the standard time zone lines? I'd like to be able to calculate what time zone a coordinate is without using a web service. I figured that time zone boundaries are mostly static and were probably decided by some committee, so there should be a CSV or GPX or KML somewhere.
I'd like to be able to check what time zone a coordinate lies in, for example:
48.856667 2.350833 is GMT+1 or CET
This is a series of files -- timezone polygons (shapefile), which you can transform into boundaries. With work on your part.
http://efele.net/maps/tz/world/
You should note that simply knowing the TZ does not guarantee that you know anything about the current correct time or date there in terms of the local calendar. Time Ex: The Isreali Knesset (parliament) decides when Daylight time starts and ends - sometimes they have chosen a date in the past. Date Ex: The Hijri Calendar changes months based on the ability of people in Mecca to actually observe the new moon from there. Cloudy days alter the date.
Askgeo.com has a Java library under commercial license. (Scroll down their page to find information about it). They charge 2 grand up front for it though, considering the amount of work they must have put in compiling loads of vector maps, etc, I can understand they want the money.
I use their free API, but you wanted something downloadable, and I think this is one of your few bets.
I tried openstreetmap and they have the data, but it would be buried in a map of Earth, not completely useful itself. Here is one on Wikipedia though: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
I recently found this data here:
https://github.com/straup/whereonearth-timezone