summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2021-05-05 01:02:59 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2021-05-05 01:02:59 +0000
commitdc9fae15fa1c7be516be53bf22ade88c35b9dba2 (patch)
tree954027df47ab2e10526321a6d60b46726dd50af5
parent717915f521b71b069798d66dba8a38faabbe05a8 (diff)
parent73a047e99c5cdda1d12d2301a3f28870dc5a45c5 (diff)
downloadicu-dc9fae15fa1c7be516be53bf22ade88c35b9dba2.tar.gz
Snap for 7336869 from 73a047e99c5cdda1d12d2301a3f28870dc5a45c5 to sc-d1-release
Change-Id: I739ad5b78456e1342299cb56410a2420f9378743
-rw-r--r--android_icu4j/api/intra/current.txt7
-rw-r--r--android_icu4j/api/legacy_platform/current.txt1
-rw-r--r--android_icu4j/libcore_bridge/src/java/com/android/i18n/timezone/CountryZonesFinder.java43
-rw-r--r--android_icu4j/libcore_bridge/src/java/com/android/icu/text/ExtendedTimeZoneNames.java80
-rw-r--r--android_icu4j/testing/src/com/android/i18n/test/timezone/CountryZonesFinderTest.java44
5 files changed, 161 insertions, 14 deletions
diff --git a/android_icu4j/api/intra/current.txt b/android_icu4j/api/intra/current.txt
index d3cc4cc87..317a84368 100644
--- a/android_icu4j/api/intra/current.txt
+++ b/android_icu4j/api/intra/current.txt
@@ -74,6 +74,13 @@ package com.android.icu.text {
method @NonNull public static com.android.icu.text.ExtendedTimeZoneNames getInstance(@NonNull android.icu.util.ULocale);
method @NonNull public android.icu.text.TimeZoneNames getTimeZoneNames();
method @Nullable public com.android.icu.text.ExtendedTimeZoneNames.MatchedTimeZone matchName(@NonNull CharSequence, int, @NonNull String);
+ method @Nullable public com.android.icu.text.ExtendedTimeZoneNames.Match matchNameToBeRenamed(@NonNull CharSequence, int, @NonNull String);
+ }
+
+ public static final class ExtendedTimeZoneNames.Match {
+ method public int getMatchLength();
+ method @NonNull public String getTzId();
+ method public boolean isDst();
}
public static class ExtendedTimeZoneNames.MatchedTimeZone {
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/libcore_bridge/src/java/com/android/icu/text/ExtendedTimeZoneNames.java b/android_icu4j/libcore_bridge/src/java/com/android/icu/text/ExtendedTimeZoneNames.java
index 57c7367bc..37c60635f 100644
--- a/android_icu4j/libcore_bridge/src/java/com/android/icu/text/ExtendedTimeZoneNames.java
+++ b/android_icu4j/libcore_bridge/src/java/com/android/icu/text/ExtendedTimeZoneNames.java
@@ -54,7 +54,55 @@ public class ExtendedTimeZoneNames {
private final ULocale locale;
private final TimeZoneNames timeZoneNames;
+/**
+ * A class representing the return result of {@link #matchName(CharSequence, int, String)}
+ *
+ * @hide
+ */
+ @IntraCoreApi
+ public static final class Match {
+
+ private final int matchLength;
+ private final @NonNull String tzId;
+ private final boolean isDst;
+ private Match(int matchLength, @NonNull String tzId, boolean isDst) {
+ this.matchLength = matchLength;
+ this.tzId = tzId;
+ this.isDst = isDst;
+ }
+
+ /**
+ * Returns the number of chars in the matched name.
+ *
+ * @hide
+ */
+ @IntraCoreApi
+ public int getMatchLength() {
+ return matchLength;
+ }
+
+ /**
+ * Returns the time zone id associated with the matched name.
+ *
+ * @hide
+ */
+ @IntraCoreApi
+ public @NonNull String getTzId() {
+ return tzId;
+ }
+
+ /**
+ * Returns true if the matched name is a display name for daylight saving time. For example,
+ * returns true for "Pacific Daylight Time", but false for "Pacific Standard Time".
+ *
+ * @hide
+ */
+ @IntraCoreApi
+ public boolean isDst() {
+ return isDst;
+ }
+ }
/**
* A class representing the return result of {@link #matchName(CharSequence, int, String)}
*
@@ -131,6 +179,38 @@ public class ExtendedTimeZoneNames {
}
/**
+ * Returns {@link Match} if a time zone name in ICU can be matched against the input
+ * CharSequence {@code s}.
+ * The best match is found by the following principles:
+ * <ul>
+ * <li>Length of the matched name. Longest name matched to the given {@code s} has the
+ * highest priority.</li>
+ * <li>The current time zone and meta zones possible in the current country have higher
+ * priority than other zones.</li>
+ * <li>If only meta zones are matched, the country/region in the locale is used to select
+ * a reference time zone. For example, if the name is "Pacific Standard Time" and the country
+ * is US, America/Los_Angeles is returned.</li>
+ * </ul>
+ *
+ * @param text input string to be matched against time zone names in ICU
+ * @param start the begin index in the CharSequence {@code s}
+ * @param currentTzId the time zone ID prioritized to be matched if multiple time zone IDs can
+ * be matched and this is one of the matched IDs.
+ * @return null if no match is found
+ *
+ * @hide
+ */
+ @IntraCoreApi
+ public @Nullable Match matchNameToBeRenamed(@NonNull CharSequence text, int start,
+ @NonNull String currentTzId) {
+ MatchedTimeZone matchedTimeZone = matchName(text, start, currentTzId);
+ if (matchedTimeZone == null) {
+ return null;
+ }
+ return new Match(matchedTimeZone.matchLength, matchedTimeZone.tzId, matchedTimeZone.isDst);
+ }
+
+ /**
* Returns {@link MatchedTimeZone} if a time zone name in ICU can be matched against the input
* CharSequence {@code s}.
* The best match is found by the following principles:
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);