Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not a complete list of time zones and their aliases #756

Closed
AlexKnyazyk opened this issue Mar 14, 2018 · 8 comments
Closed

Not a complete list of time zones and their aliases #756

AlexKnyazyk opened this issue Mar 14, 2018 · 8 comments

Comments

@AlexKnyazyk
Copy link

AlexKnyazyk commented Mar 14, 2018

In our android project we use WinZoneProviderSPI.NAME_BASED_MAP for converting the iana timeszone to windows. But we are forced to use a crutch like this, because on some devices the timeszone is determined by its alias. Link on source Wiki. The first value is something that is not in the library but is an alias, the second value is what is.

Map<String, String> aliasMap = new HashMap<>();
aliasMap.put("Asia/Ho_Chi_Minh", "Asia/Saigon");
aliasMap.put("America/Kentucky/Louisville", "America/Louisville");
aliasMap.put("Pacific/Pohnpei", "Pacific/Ponape");
aliasMap.put("America/Atikokan", "America/Coral_Harbour");
aliasMap.put("America/Argentina/Buenos_Aires", "America/Buenos_Aires");
aliasMap.put("America/Indiana/Indianapolis", "America/Indianapolis");
aliasMap.put("America/Argentina/Jujuy", "America/Jujuy");
aliasMap.put("Asia/Kathmandu", "Asia/Katmandu");
aliasMap.put("Pacific/Chuuk", "Pacific/Truk");
aliasMap.put("America/Argentina/Mendoza", "America/Mendoza");
aliasMap.put("Atlantic/Faroe", "Atlantic/Faeroe");
aliasMap.put("Asia/Yangon", "Asia/Rangoon");
aliasMap.put("America/Argentina/Cordoba", "America/Cordoba");
aliasMap.put("Asia/Kolkata", "Asia/Calcutta");
aliasMap.put("America/Argentina/Catamarca", "America/Catamarca");
aliasMap.put("America/Argentina/ComodRivadavia", "America/Catamarca");
aliasMap.put("Europe/Tiraspol", "Europe/Chisinau");
aliasMap.put("America/Ensenada", "America/Tijuana");
aliasMap.put("America/Fort_Wayne", "America/Indianapolis");
aliasMap.put("America/Porto_Acre", "America/Rio_Branco");
aliasMap.put("Asia/Tel_Aviv", "Asia/Jerusalem");
aliasMap.put("Asia/Ulan_Bator", "Asia/Ulaanbaatar");
aliasMap.put("Antarctica/South_Pole", "Pacific/Auckland");
aliasMap.put("Asia/Kashgar", "Asia/Urumqi");
aliasMap.put("America/Rosario", "America/Cordoba");
aliasMap.put("Asia/Dacca", "Asia/Dhaka");
aliasMap.put("Australia/Yancowinna", "Australia/Broken_Hill");
aliasMap.put("Asia/Ashkhabad", "Asia/Ashgabat");
aliasMap.put("America/Virgin", "America/Port_of_Spain");
aliasMap.put("Asia/Harbin", "Asia/Shanghai");
aliasMap.put("Asia/Macao", "Asia/Macau");
aliasMap.put("Asia/Thimbu", "Asia/Thimphu");
aliasMap.put("Australia/Canberra", "Australia/Sydney");
aliasMap.put("Atlantic/Jan_Mayen", "Europe/Oslo");
aliasMap.put("Asia/Chungking", "Asia/Shanghai");
aliasMap.put("Asia/Chongqing", "Asia/Shanghai");
aliasMap.put("America/Atka", "America/Adak");
aliasMap.put("Europe/Belfast", "Europe/London");
aliasMap.put("Pacific/Yap", "Pacific/Truk");
aliasMap.put("Africa/Timbuktu", "Africa/Abidjan");
aliasMap.put("America/Shiprock", "America/Denver");
aliasMap.put("Asia/Ujung_Pandang", "Asia/Makassar");

@MenoData
Copy link
Owner

MenoData commented Mar 14, 2018

Well, the following test code shows that the aliases can be recognized. You see different timezone identifiers but exactly the same rules:

	Timezone.of("Asia/Yangon").dump(System.out);
	System.out.println("----------------------");
	Timezone.of("Asia/Rangoon").dump(System.out);
	System.out.println("----------------------");

Start Of Dump =>
*** Timezone-ID:

Asia/Yangon
*** Strategy:
net.time4j.tz.TransitionResolver:[gap=PUSH_FORWARD,overlap=LATER_OFFSET]
*** History:
Transition at: 1942-04-30T17:30:00Z from +06:30 to +09:00, DST=+00:00
Transition at: 1945-05-02T15:00:00Z from +09:00 to +06:30, DST=+00:00
<= End Of Dump


Start Of Dump =>
*** Timezone-ID:

Asia/Rangoon
*** Strategy:
net.time4j.tz.TransitionResolver:[gap=PUSH_FORWARD,overlap=LATER_OFFSET]
*** History:
Transition at: 1942-04-30T17:30:00Z from +06:30 to +09:00, DST=+00:00
Transition at: 1945-05-02T15:00:00Z from +09:00 to +06:30, DST=+00:00
<= End Of Dump


Ah wait a moment, your question is about an internal detail of winzone-mapping. I will look into it.

@MenoData
Copy link
Owner

MenoData commented Mar 14, 2018

Actually, Time4J supports aliases in general but only in one direction, namely resolving aliases internally to the real IANA-identifiers. Similar direction is valid for windows-zone-identifiers.

The non-public-api-map you are actually using contains entries like:

Israel Standard Time={001=[WINDOWS~Asia/Jerusalem], IL=[WINDOWS~Asia/Jerusalem]}

This map is optimized for the purpose of look up of winzones in combination with a country-id and does not need to know about aliases like "Asia/Tel_Aviv" (in this direction). I have now following new methods for the reverse direction in mind:

class Timezone:

static TZID normalize(TZID) // resolves aliases to normal identifiers

class WindowsZone:

static WindowsZone from(TZID, Locale)

@MenoData MenoData added this to the F4.36: Small enhancements milestone Mar 14, 2018
MenoData added a commit that referenced this issue Mar 16, 2018
MenoData added a commit to MenoData/TZData that referenced this issue Mar 16, 2018
MenoData added a commit that referenced this issue Mar 17, 2018
MenoData added a commit that referenced this issue Mar 17, 2018
MenoData added a commit that referenced this issue Mar 17, 2018
MenoData added a commit that referenced this issue Mar 17, 2018
MenoData added a commit that referenced this issue Mar 17, 2018
MenoData added a commit to MenoData/TZData that referenced this issue Mar 17, 2018
MenoData added a commit that referenced this issue Mar 18, 2018
see issue #756
@MenoData
Copy link
Owner

MenoData commented Mar 24, 2018

Now I have released Time4A-v3.41 and the misc-module in version v3.41. Following features have been added so you should be able to solve your problem without accessing internal implementations:

  • normalization feature in class Timezone
  • reverse engineering of winzone names, see the new static methods public static String toString(tzid, locale) in the class WindowsZone, alias names included

Some notes about your alias map:

  • It should be no longer necessary.
  • The informations given in Wikipedia (the base of your alias map) is not up-to-date. Meanwhile the tzdb-maintainers have redefined some identifiers to be either the "real" identifiers or just links to identifiers, for example: "Asia/Yangon" is now the real identifier while the former tzid "Asia/Rangoon" is now only a link to "Asia/Yangon". The method WindowsZone.toString("Asia/Yangon", new Locale("en", "MM")) can yield the windows zone name "Myanmar Standard Time" and does it also with the old tzid "Asia/Rangoon" as parameter. For any other country, you can use the fallback locale new Locale("", "001").

I appreciate any feedback very much if the new version works for you.

@MenoData
Copy link
Owner

Now I have even released the misc-module in the version v3.41.1 which contains an automatic fallback to territory "001" (the CLDR-symbol for "worldwide") if the windows zone name does not exist for a given country identifier. So your issue is pretty much solved (the tzdata-module which is necessary for normalizing any aliases is already included in the latest Time4A-version).

@AlexKnyazyk
Copy link
Author

@MenoData Thanks, Your changes help me :)
i use such solution:
WindowsZone.toString(TimeZone.getDefault().getID(), Locale.ENGLISH);
But i find some problem, i use 2 library dependencies:

implementation "net.time4j:time4j-android:4.3-2019a"
implementation ("net.time4j:time4j-misc:3.41.1") {
        exclude module: 'time4j-core'
        exclude module: 'time4j-i18n'
}

I first tried to use the latest version of the "misc" library 4.38, but it is not working with them :(

@MenoData
Copy link
Owner

MenoData commented May 4, 2019

Thanks for your feedback. I have already learnt that Android architecture is not optimized for a modular Time4A, so I think the winzone-classes should just be added to Time4A directly - without an extra aar-file. However, I should then look for an option how to register or unregister these additional tz-identifiers to the tz-repository of Time4A.

@MenoData MenoData reopened this May 4, 2019
@MenoData MenoData added the time4a label May 4, 2019
MenoData referenced this issue in MenoData/Time4A May 13, 2019
@MenoData
Copy link
Owner

MenoData commented May 13, 2019

Time4A with version 4.4 contains the win-zone-support, so only one dependency is needed (not yet released however):

implementation "net.time4j:time4j-android:4.4-2019a"

Example for working code in Time4A:

    try {
        TZID winzoneID = WindowsZone.of("Romance Standard Time").resolveSmart(Locale.FRANCE);
        WindowsZone.registerAsTimezone();
        String winzoneName = Timezone.of(winzoneID).getDisplayName(
                    NameStyle.LONG_STANDARD_TIME, 
                    Locale.FRANCE);
        Log.i("TIME4A", "Winzone: " + winzoneID.canonical() + "=>" + winzoneName);
    } catch (IllegalArgumentException ex) {
        Log.e("TIME4A", "Winzone not known.");
    }

Output: "Winzone: WINDOWS~Europe/Paris=>Romance Standard Time"

Attention: If you need expressions like Timezone.of(winzoneID) or want to parse names like "Romance Standard Time" in date-time-patterns using ChronoFormatter then you need to call WindowsZone.registerAsTimezone(). This can best be done directly after using ApplicationStarter in the initialization of Time4A.

@MenoData
Copy link
Owner

For your information: Time4A (4.4-2019a) has been released today.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants