diff options
author | Almaz Mingaleev <mingaleev@google.com> | 2021-04-29 19:13:18 +0000 |
---|---|---|
committer | Almaz Mingaleev <mingaleev@google.com> | 2021-05-04 15:59:55 +0000 |
commit | 0f04905756ee81e16b9174822eb020a6fa5b3cb1 (patch) | |
tree | af344e20b6f8f749435186985eb9b2a7e90565c5 | |
parent | d29d01e875f1df8dac658c5e9a528159d63c0cd6 (diff) | |
download | icu-0f04905756ee81e16b9174822eb020a6fa5b3cb1.tar.gz |
Add findCanonicalTimeZoneId method.
Returns replacements for deprecated time zones. For example,
America/Godthab was replaced with America/Nuuk.
Bug: 172934905
Test: atest CtsIcuTestCases:com.android.i18n.test.timezone
Change-Id: I5c5b5e28f7d41af4bc7d2fc7a547a283132190d4
3 files changed, 74 insertions, 14 deletions
diff --git a/android_icu4j/api/legacy_platform/current.txt b/android_icu4j/api/legacy_platform/current.txt index a81a0c650..692b2b1bf 100644 --- a/android_icu4j/api/legacy_platform/current.txt +++ b/android_icu4j/api/legacy_platform/current.txt @@ -81,6 +81,7 @@ package com.android.i18n.timezone { } public final class CountryZonesFinder { + method @Nullable public String findCanonicalTimeZoneId(String); method public java.util.List<java.lang.String> lookupAllCountryIsoCodes(); method public com.android.i18n.timezone.CountryTimeZones lookupCountryTimeZones(String); method public java.util.List<com.android.i18n.timezone.CountryTimeZones> lookupCountryTimeZonesForZoneId(String); diff --git a/android_icu4j/libcore_bridge/src/java/com/android/i18n/timezone/CountryZonesFinder.java b/android_icu4j/libcore_bridge/src/java/com/android/i18n/timezone/CountryZonesFinder.java index 80a316e1f..61d9a1895 100644 --- a/android_icu4j/libcore_bridge/src/java/com/android/i18n/timezone/CountryZonesFinder.java +++ b/android_icu4j/libcore_bridge/src/java/com/android/i18n/timezone/CountryZonesFinder.java @@ -19,6 +19,7 @@ package com.android.i18n.timezone; import static com.android.i18n.timezone.XmlUtils.normalizeCountryIso; import com.android.i18n.timezone.CountryTimeZones.TimeZoneMapping; +import libcore.util.Nullable; import java.util.ArrayList; import java.util.Collections; @@ -57,10 +58,11 @@ public final class CountryZonesFinder { /** * Returns an immutable list of {@link CountryTimeZones} for countries that use the specified - * time zone. An exact, case-sensitive match is performed on the zone ID. If the match but the method also - * checks for alternative zone IDs. This method never returns null and will usually return a - * list containing a single element. It can return an empty list if the zone ID is - * not recognized or it is not associated with a country. + * time zone. An exact, case-sensitive match is performed on the zone ID. Search is done + * over currently used time zone IDs and also over no longer used deprecated(alternative) IDs. + * This method never returns null and will usually return a list containing a single element. + * It can return an empty list if the zone ID is not recognized or it is not associated with a + * country. */ @libcore.api.CorePlatformApi public List<CountryTimeZones> lookupCountryTimeZonesForZoneId(String zoneId) { @@ -104,4 +106,37 @@ public final class CountryZonesFinder { } return null; } + + /** + * Returns a canonical time zone ID for the {@code timeZoneId} specified. It is intended for use + * when behavioral equivalence of time zones needs to be determined. + * + * <p>When a time zone ID is returned, it is guaranteed to have the same offset / daylight + * savings behavior as the argument, but it might be used in a different country and could + * have different I18N properties like display name. The original {@code timeZoneId} will + * often be returned. + * + * <p>If {@code timeZoneId} is unknown or not associated with a country, {@code null} is + * returned. e.g. time zones such as Etc/GMT+-XX. + * + * This method behavior is based on tzlookup.xml file and works with Olson IDs attached to + * countries, unlike {@link android.icu.util.TimeZone} which works with wider set of arguments. + */ + @libcore.api.CorePlatformApi + @Nullable + public String findCanonicalTimeZoneId(String timeZoneId) { + for (CountryTimeZones countryTimeZones : countryTimeZonesList) { + + // notafter is ignored as timeZoneId might be deprecated a while ago + List<TimeZoneMapping> countryTimeZoneMappings = countryTimeZones.getTimeZoneMappings(); + for (TimeZoneMapping timeZoneMapping : countryTimeZoneMappings) { + if (timeZoneMapping.getTimeZoneId().equals(timeZoneId) + || timeZoneMapping.getAlternativeIds().contains(timeZoneId)) { + return timeZoneMapping.getTimeZoneId(); + } + } + } + + return null; + } } diff --git a/android_icu4j/testing/src/com/android/i18n/test/timezone/CountryZonesFinderTest.java b/android_icu4j/testing/src/com/android/i18n/test/timezone/CountryZonesFinderTest.java index 64ec0fd0d..549c8899f 100644 --- a/android_icu4j/testing/src/com/android/i18n/test/timezone/CountryZonesFinderTest.java +++ b/android_icu4j/testing/src/com/android/i18n/test/timezone/CountryZonesFinderTest.java @@ -16,22 +16,26 @@ package com.android.i18n.test.timezone; -import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import android.icu.testsharding.MainTestShard; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; import com.android.i18n.timezone.CountryTimeZones; import com.android.i18n.timezone.CountryTimeZones.TimeZoneMapping; import com.android.i18n.timezone.CountryZonesFinder; -import android.icu.testsharding.MainTestShard; +import org.junit.Test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.fail; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; @MainTestShard public class CountryZonesFinderTest { @@ -119,6 +123,26 @@ public class CountryZonesFinderTest { assertNull(countryZonesFinder.lookupCountryTimeZones("DOES_NOT_EXIST")); } + @Test + public void findCanonicalTimeZoneId() { + TimeZoneMapping usesNewZoneId = timeZoneMappingWithAlts("America/Detroit", + list("US/Michigan")); + TimeZoneMapping usesOldZoneId = timeZoneMappingWithAlts("US/Central", + list("America/Chicago")); + CountryTimeZones countryWithAlternativeZones = CountryTimeZones.createValidated( + "us", "America/Detroit" /* defaultTimeZoneId */, false /* defaultTimeZoneBoost */, + false /* everUsesUtc */, + list(usesNewZoneId, usesOldZoneId), + "debug info"); + CountryZonesFinder countryZonesFinder = + CountryZonesFinder.createForTests(list(countryWithAlternativeZones)); + + assertEquals(countryZonesFinder.findCanonicalTimeZoneId("America/Chicago"), "US/Central"); + assertEquals(countryZonesFinder.findCanonicalTimeZoneId("US/Michigan"), "America/Detroit"); + assertEquals(countryZonesFinder.findCanonicalTimeZoneId("America/Detroit"), "America/Detroit"); + assertNull(countryZonesFinder.findCanonicalTimeZoneId("Mars/Base")); + } + private static <X> void assertEqualsAndImmutable(List<X> expected, List<X> actual) { assertEquals(expected, actual); assertImmutableList(actual); |