Closed AlexKnyazyk closed 5 years ago
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.
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)
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:
Timezone
public static String toString(tzid, locale)
in the class WindowsZone
, alias names includedSome notes about your alias map:
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.
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).
@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 :(
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.
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.
For your information: Time4A (4.4-2019a) has been released today.
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.