Android patch: Patch 11.0.13-ga java.time implementation and tests

Implementation patches:
1. SystemClock.instant() reverts to the existing implementation
   until we implement nanosecond-level resolution of the clock
2. DateTimeFormatter.localizedBy is re-implemented by using ICU.
3. LocalDate.getEra() returns a backward-compatible type

Javadoc changes
4. Trivial javadoc fix in DateTimeFormatterBuilder. It's a upstream bug.
5. Hide localizedBy() in javadoc until we expose the API later.

Test patches: See inline comments

Bug: 180577079
Test: CtsLibcoreTestCases
Test: CtsLibcoreOjTestCases
Change-Id: I240273ff55ea6e6da7abf0b0c8c0d02e01700e69
diff --git a/luni/src/main/java/libcore/icu/ICU.java b/luni/src/main/java/libcore/icu/ICU.java
index 7a07a0b..784a24d 100644
--- a/luni/src/main/java/libcore/icu/ICU.java
+++ b/luni/src/main/java/libcore/icu/ICU.java
@@ -609,4 +609,24 @@
               .setKeywordValue("calendar", calendarType);
       return ExtendedCalendar.getInstance(uLocale);
   }
+
+  /**
+   * Converts CLDR LDML short time zone id to an ID that can be recognized by
+   * {@link java.util.TimeZone#getTimeZone(String)}.
+   * @param cldrShortTzId
+   * @return null if no tz id can be matched to the short id.
+   */
+  public static String convertToTzId(String cldrShortTzId) {
+    if (cldrShortTzId == null) {
+      return null;
+    }
+    String tzid = ULocale.toLegacyType("tz", cldrShortTzId);
+    // ULocale.toLegacyType() returns the lower case of the input ID if it matches the spec, but
+    // it's not a valid tz id.
+    if (tzid == null || tzid.equals(cldrShortTzId.toLowerCase(Locale.ROOT))) {
+      return null;
+    }
+    return tzid;
+  }
+
 }
diff --git a/ojluni/src/main/java/java/time/Clock.java b/ojluni/src/main/java/java/time/Clock.java
index 37e723e..fb0255c 100644
--- a/ojluni/src/main/java/java/time/Clock.java
+++ b/ojluni/src/main/java/java/time/Clock.java
@@ -522,6 +522,8 @@
         }
         @Override
         public Instant instant() {
+            // BEGIN Android-changed: Use OpenJDK 8 implementation until getNanoTimeAdjustment() is supported.
+            /*
             // Take a local copy of offset. offset can be updated concurrently
             // by other threads (even if we haven't made it volatile) so we will
             // work with a local copy.
@@ -556,6 +558,9 @@
                 }
             }
             return Instant.ofEpochSecond(localOffset, adjustment);
+             */
+            return Instant.ofEpochMilli(millis());
+            // END Android-changed: Use OpenJDK 8 implementation until getNanoTimeAdjustment() is supported.
         }
         @Override
         public boolean equals(Object obj) {
diff --git a/ojluni/src/main/java/java/time/LocalDate.java b/ojluni/src/main/java/java/time/LocalDate.java
index 85f84d3..17325d5 100644
--- a/ojluni/src/main/java/java/time/LocalDate.java
+++ b/ojluni/src/main/java/java/time/LocalDate.java
@@ -74,6 +74,7 @@
 import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
 import static java.time.temporal.ChronoField.YEAR;
 
+import dalvik.annotation.codegen.CovariantReturnType;
 import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
@@ -81,6 +82,7 @@
 import java.io.ObjectInputStream;
 import java.io.Serializable;
 import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.Era;
 import java.time.chrono.IsoEra;
 import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
@@ -738,7 +740,9 @@
      * @return the IsoEra applicable at this date, not null
      */
     @Override // override for Javadoc
-    public IsoEra getEra() {
+    // Android-changed: To match OpenJDK 11 API, this API returns IsoEra type after Android T.
+    @CovariantReturnType(returnType = java.time.chrono.IsoEra.class, presentAfter = 33)
+    public Era getEra() {
         return (getYear() >= 1 ? IsoEra.CE : IsoEra.BCE);
     }
 
diff --git a/ojluni/src/main/java/java/time/format/DateTimeFormatter.java b/ojluni/src/main/java/java/time/format/DateTimeFormatter.java
index 199313d..ab0db94 100644
--- a/ojluni/src/main/java/java/time/format/DateTimeFormatter.java
+++ b/ojluni/src/main/java/java/time/format/DateTimeFormatter.java
@@ -96,8 +96,9 @@
 import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
-import sun.util.locale.provider.TimeZoneNameUtility;
+import libcore.icu.ICU;
 
 /**
  * Formatter for printing and parsing date-time objects.
@@ -1438,6 +1439,7 @@
         return locale;
     }
 
+    // Android-changed: Remove javadoc reference to #localizedBy(Locale)
     /**
      * Returns a copy of this formatter with a new locale.
      * <p>
@@ -1445,16 +1447,11 @@
      * localization, such as the text or localized pattern.
      * <p>
      * The locale is stored as passed in, without further processing.
-     * If the locale has <a href="../../util/Locale.html#def_locale_extension">
-     * Unicode extensions</a>, they may be used later in text
-     * processing. To set the chronology, time-zone and decimal style from
-     * unicode extensions, see {@link #localizedBy localizedBy()}.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param locale  the new locale, not null
      * @return a formatter based on this formatter with the requested locale, not null
-     * @see #localizedBy(Locale)
      */
     public DateTimeFormatter withLocale(Locale locale) {
         if (this.locale.equals(locale)) {
@@ -1502,7 +1499,9 @@
                        DecimalStyle.of(locale) : decimalStyle;
         String tzType = locale.getUnicodeLocaleType("tz");
         ZoneId z  = tzType != null ?
-                    TimeZoneNameUtility.convertLDMLShortID(tzType)
+                    // Android changed: Use ICU on Android.
+                    // TimeZoneNameUtility.convertLDMLShortID(tzType)
+                    Optional.ofNullable(ICU.convertToTzId(tzType))
                         .map(ZoneId::of)
                         .orElse(zone) :
                     zone;
diff --git a/ojluni/src/main/java/java/time/format/DateTimeFormatterBuilder.java b/ojluni/src/main/java/java/time/format/DateTimeFormatterBuilder.java
index 2e8bd4c..fb1b318 100644
--- a/ojluni/src/main/java/java/time/format/DateTimeFormatterBuilder.java
+++ b/ojluni/src/main/java/java/time/format/DateTimeFormatterBuilder.java
@@ -698,7 +698,7 @@
      * the minimum and maximum width. In strict mode, if the minimum and maximum widths
      * are equal and there is no decimal point then the parser will
      * participate in adjacent value parsing, see
-     * {@link appendValue(java.time.temporal.TemporalField, int)}. When parsing in lenient mode,
+     * {@link #appendValue(java.time.temporal.TemporalField, int)}. When parsing in lenient mode,
      * the minimum width is considered to be zero and the maximum is nine.
      * <p>
      * If the value cannot be obtained then an exception will be thrown.
diff --git a/ojluni/src/main/resources/hijrah-config-umalqura.properties b/ojluni/src/main/resources/java/time/chrono/hijrah-config-islamic-umalqura.properties
similarity index 100%
rename from ojluni/src/main/resources/hijrah-config-umalqura.properties
rename to ojluni/src/main/resources/java/time/chrono/hijrah-config-islamic-umalqura.properties
diff --git a/ojluni/src/test/java/time/tck/java/time/TCKLocalDate.java b/ojluni/src/test/java/time/tck/java/time/TCKLocalDate.java
index 42f6ecb..faf81d1 100644
--- a/ojluni/src/test/java/time/tck/java/time/TCKLocalDate.java
+++ b/ojluni/src/test/java/time/tck/java/time/TCKLocalDate.java
@@ -101,6 +101,7 @@
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
+import java.time.chrono.Era;
 import java.time.chrono.IsoChronology;
 import java.time.chrono.IsoEra;
 import java.time.format.DateTimeFormatter;
@@ -2386,7 +2387,9 @@
     // ----------------------------------------------------------------
     @Test
     public void test_getEra() {
-        IsoEra isoEra = LocalDate.MAX.getEra();
+        // Android-changed: getEra() returns Era for backward compatibility.
+        // IsoEra isoEra = LocalDate.MAX.getEra();
+        Era isoEra = LocalDate.MAX.getEra();
         assertSame(isoEra,IsoEra.CE);
         assertSame(LocalDate.MIN.getEra(),IsoEra.BCE);
     }
@@ -2463,14 +2466,20 @@
     @DataProvider(name="datesUntil")
     public Object[][] provider_datesUntil() {
         return new Object[][] {
+                // Android-removed: The range to max date takes too much memory and time.
+                /*
                 {MIN_DATE, MIN_DATE},
                 {MIN_DATE, MAX_DATE},
                 {MAX_DATE, MAX_DATE},
+                */
                 {date(2015,10,1), date(2015,10,2)},
                 {date(2015,10,1), date(2015,11,1)},
                 {date(2015,10,31), date(2015,11,1)},
+                // Android-removed: The range to max date takes too much memory and time.
+                /*
                 {date(2015,10,1), MAX_DATE},
                 {MIN_DATE, date(2015,10,1)}
+                */
         };
     }
 
@@ -2484,6 +2493,8 @@
     @DataProvider(name="datesUntilSteps")
     public Object[][] provider_datesUntil_steps() {
         List<Object[]> data = new ArrayList<>(Arrays.asList(new Object[][] {
+            // Android-removed: The range to max date takes too much memory and time.
+            /*
             {MIN_DATE, MAX_DATE, Period.ofYears(Year.MAX_VALUE)},
             {MIN_DATE, MAX_DATE, Period.ofDays(2)},
             {MIN_DATE, MAX_DATE, Period.of(1,2,3)},
@@ -2496,6 +2507,7 @@
             {MIN_DATE, MAX_DATE.minusYears(1), Period.ofYears(Year.MAX_VALUE)},
             {MAX_DATE.minusMonths(1), MAX_DATE, Period.ofMonths(1)},
             {date(Year.MAX_VALUE, 2, 20), MAX_DATE, Period.of(0, 1, 1)},
+            */
             {date(2015,1,1), date(2016,1,1), Period.ofYears(1)},
             {date(2015,1,1), date(2016,1,1), Period.ofDays(365)},
             {date(2015,1,1), date(2016,1,1), Period.ofDays(366)},
@@ -2517,12 +2529,15 @@
             {date(2015,1,31), date(2043,1,31), Period.of(0,0,1460)},
             {date(2015,1,31), date(2043,1,31), Period.of(0,0,1461)},
             {date(2015,1,31), date(2043,2,1), Period.of(0,0,1461)},
+            // Android-removed: The range to max date takes too much memory and time.
+            /*
             {date(2015,1,31), MAX_DATE, Period.of(10,100,1000)},
             {date(2015,1,31), MAX_DATE, Period.of(1000000,10000,100000)},
             {date(2015,1,31), MAX_DATE, Period.ofDays(10000000)},
             {date(2015,1,31), MAX_DATE, Period.ofDays(Integer.MAX_VALUE)},
             {date(2015,1,31), MAX_DATE, Period.ofMonths(Integer.MAX_VALUE)},
             {date(2015,1,31), MAX_DATE, Period.ofYears(Integer.MAX_VALUE)}
+            */
         }));
         LocalDate start = date(2014, 1, 15);
         LocalDate end = date(2015, 3, 4);
diff --git a/ojluni/src/test/java/time/test/java/time/TestClock_System.java b/ojluni/src/test/java/time/test/java/time/TestClock_System.java
index 55ef1cd..be24242 100644
--- a/ojluni/src/test/java/time/test/java/time/TestClock_System.java
+++ b/ojluni/src/test/java/time/test/java/time/TestClock_System.java
@@ -126,6 +126,8 @@
                         + time.getNano();
     }
 
+    // Android-changed: Disable the test until the SystemClock has higher resolution.
+    @Test(enabled = false)
     public void test_ClockResolution() {
         Clock highestUTC = Clock.systemUTC();
 
@@ -394,6 +396,8 @@
                 System.currentTimeMillis()/1000 + 1024);
     }
 
+    // Android-changed: Disable the test until the SystemClock has higher resolution.
+    @Test(enabled = false)
     public void test_OffsetLimits() throws IllegalAccessException {
         System.out.println("*** Testing limits ***");
         SystemClockOffset.testWithOffset("System.currentTimeMillis()/1000 - MAX_OFFSET + 1",
diff --git a/ojluni/src/test/java/time/test/java/time/chrono/TestEraDisplayName.java b/ojluni/src/test/java/time/test/java/time/chrono/TestEraDisplayName.java
index 27fc1ae..d2d655f 100644
--- a/ojluni/src/test/java/time/test/java/time/chrono/TestEraDisplayName.java
+++ b/ojluni/src/test/java/time/test/java/time/chrono/TestEraDisplayName.java
@@ -66,16 +66,22 @@
 
             // JapaneseEra
             { JapaneseEra.MEIJI,    TextStyle.FULL,     Locale.US,      "Meiji" },
-            { JapaneseEra.TAISHO,   TextStyle.FULL,     Locale.US,      "Taisho" },
-            { JapaneseEra.SHOWA,    TextStyle.FULL,     Locale.US,      "Showa" },
+            // Android-changed: Android uses CLDR data.
+            // { JapaneseEra.TAISHO,   TextStyle.FULL,     Locale.US,      "Taisho" },
+            // { JapaneseEra.SHOWA,    TextStyle.FULL,     Locale.US,      "Showa" },
+            { JapaneseEra.TAISHO,   TextStyle.FULL,     Locale.US,      "Taishō" },
+            { JapaneseEra.SHOWA,    TextStyle.FULL,     Locale.US,      "Shōwa" },
             { JapaneseEra.HEISEI,   TextStyle.FULL,     Locale.US,      "Heisei" },
             { JapaneseEra.MEIJI,    TextStyle.FULL,     Locale.JAPAN,   "\u660e\u6cbb" },
             { JapaneseEra.TAISHO,   TextStyle.FULL,     Locale.JAPAN,   "\u5927\u6b63" },
             { JapaneseEra.SHOWA,    TextStyle.FULL,     Locale.JAPAN,   "\u662d\u548c" },
             { JapaneseEra.HEISEI,   TextStyle.FULL,     Locale.JAPAN,   "\u5e73\u6210" },
             { JapaneseEra.MEIJI,    TextStyle.SHORT,    Locale.US,      "Meiji" },
-            { JapaneseEra.TAISHO,   TextStyle.SHORT,    Locale.US,      "Taisho" },
-            { JapaneseEra.SHOWA,    TextStyle.SHORT,    Locale.US,      "Showa" },
+            // Android-changed: Android uses CLDR data.
+            // { JapaneseEra.TAISHO,   TextStyle.SHORT,    Locale.US,      "Taisho" },
+            // { JapaneseEra.SHOWA,    TextStyle.SHORT,    Locale.US,      "Showa" },
+            { JapaneseEra.TAISHO,   TextStyle.SHORT,    Locale.US,      "Taishō" },
+            { JapaneseEra.SHOWA,    TextStyle.SHORT,    Locale.US,      "Shōwa" },
             { JapaneseEra.HEISEI,   TextStyle.SHORT,    Locale.US,      "Heisei" },
             { JapaneseEra.MEIJI,    TextStyle.SHORT,    Locale.JAPAN,   "\u660e\u6cbb" },
             { JapaneseEra.TAISHO,   TextStyle.SHORT,    Locale.JAPAN,   "\u5927\u6b63" },
@@ -91,32 +97,59 @@
             { JapaneseEra.HEISEI,   TextStyle.NARROW,   Locale.JAPAN,   "H" },
 
             // ThaiBuddhistEra
-            { ThaiBuddhistEra.BEFORE_BE,    TextStyle.FULL, Locale.US,      "BC" },
+            // Android-changed: Android uses CLDR data.
+            // { ThaiBuddhistEra.BEFORE_BE,    TextStyle.FULL, Locale.US,      "BC" },
+            // { ThaiBuddhistEra.BE,           TextStyle.FULL, Locale.US,      "BE" },
+            // { ThaiBuddhistEra.BEFORE_BE,    TextStyle.FULL, THAI,           "BC" },
+            // { ThaiBuddhistEra.BE,           TextStyle.FULL, THAI,
+            //   "\u0e1e\u0e38\u0e17\u0e18\u0e28\u0e31\u0e01\u0e23\u0e32\u0e0a" },
+            // { ThaiBuddhistEra.BEFORE_BE,    TextStyle.SHORT, Locale.US,     "BC" },
+            // { ThaiBuddhistEra.BE,           TextStyle.SHORT, Locale.US,     "BE" },
+            // { ThaiBuddhistEra.BEFORE_BE,    TextStyle.SHORT, THAI,
+            //   "\u0e1b\u0e35\u0e01\u0e48\u0e2d\u0e19\u0e04\u0e23\u0e34\u0e2a" +
+            //     "\u0e15\u0e4c\u0e01\u0e32\u0e25\u0e17\u0e35\u0e48" },
+            // { ThaiBuddhistEra.BE,           TextStyle.SHORT, THAI,  "\u0e1e.\u0e28." },
+            // { ThaiBuddhistEra.BEFORE_BE,    TextStyle.NARROW, Locale.US,    "BC" },
+            // { ThaiBuddhistEra.BE,           TextStyle.NARROW, Locale.US,    "BE" },
+            // { ThaiBuddhistEra.BEFORE_BE,    TextStyle.NARROW, THAI,         "BC" },
+            // { ThaiBuddhistEra.BE,           TextStyle.NARROW, THAI,         "\u0e1e.\u0e28." },
+            { ThaiBuddhistEra.BEFORE_BE,    TextStyle.FULL, Locale.US,      "0" },
             { ThaiBuddhistEra.BE,           TextStyle.FULL, Locale.US,      "BE" },
-            { ThaiBuddhistEra.BEFORE_BE,    TextStyle.FULL, THAI,           "BC" },
+            { ThaiBuddhistEra.BEFORE_BE,    TextStyle.FULL, THAI,           "0" },
             { ThaiBuddhistEra.BE,           TextStyle.FULL, THAI,
                 "\u0e1e\u0e38\u0e17\u0e18\u0e28\u0e31\u0e01\u0e23\u0e32\u0e0a" },
-            { ThaiBuddhistEra.BEFORE_BE,    TextStyle.SHORT, Locale.US,     "BC" },
+            { ThaiBuddhistEra.BEFORE_BE,    TextStyle.SHORT, Locale.US,     "0" },
             { ThaiBuddhistEra.BE,           TextStyle.SHORT, Locale.US,     "BE" },
-            { ThaiBuddhistEra.BEFORE_BE,    TextStyle.SHORT, THAI,
-                "\u0e1b\u0e35\u0e01\u0e48\u0e2d\u0e19\u0e04\u0e23\u0e34\u0e2a" +
-                "\u0e15\u0e4c\u0e01\u0e32\u0e25\u0e17\u0e35\u0e48" },
+            { ThaiBuddhistEra.BEFORE_BE,    TextStyle.SHORT, THAI,          "0" },
             { ThaiBuddhistEra.BE,           TextStyle.SHORT, THAI,  "\u0e1e.\u0e28." },
-            { ThaiBuddhistEra.BEFORE_BE,    TextStyle.NARROW, Locale.US,    "BC" },
+            { ThaiBuddhistEra.BEFORE_BE,    TextStyle.NARROW, Locale.US,    "0" },
             { ThaiBuddhistEra.BE,           TextStyle.NARROW, Locale.US,    "BE" },
-            { ThaiBuddhistEra.BEFORE_BE,    TextStyle.NARROW, THAI,         "BC" },
+            { ThaiBuddhistEra.BEFORE_BE,    TextStyle.NARROW, THAI,         "0" },
             { ThaiBuddhistEra.BE,           TextStyle.NARROW, THAI,         "\u0e1e.\u0e28." },
 
             // MinguoEra
-            { MinguoEra.BEFORE_ROC, TextStyle.FULL,     Locale.US,      "Before R.O.C." },
+            // Android-changed: Android uses CLDR data.
+            // { MinguoEra.BEFORE_ROC, TextStyle.FULL,     Locale.US,      "Before R.O.C." },
+            // { MinguoEra.ROC,        TextStyle.FULL,     Locale.US,      "Minguo" },
+            // { MinguoEra.BEFORE_ROC, TextStyle.FULL,     Locale.TAIWAN,  "\u6c11\u570b\u524d" },
+            // { MinguoEra.ROC,        TextStyle.FULL,     Locale.TAIWAN,  "\u6c11\u570b" },
+            // { MinguoEra.BEFORE_ROC, TextStyle.SHORT,    Locale.US,      "Before R.O.C." },
+            // { MinguoEra.ROC,        TextStyle.SHORT,    Locale.US,      "Minguo" },
+            // { MinguoEra.BEFORE_ROC, TextStyle.SHORT,    Locale.TAIWAN,  "\u6c11\u570b\u524d" },
+            // { MinguoEra.ROC,        TextStyle.SHORT,    Locale.TAIWAN,  "\u6c11\u570b" },
+            // { MinguoEra.BEFORE_ROC, TextStyle.NARROW,   Locale.US,      "Before R.O.C." },
+            // { MinguoEra.ROC,        TextStyle.NARROW,   Locale.US,      "Minguo" },
+            // { MinguoEra.BEFORE_ROC, TextStyle.NARROW,   Locale.TAIWAN,  "\u6c11\u570b\u524d" },
+            // { MinguoEra.ROC,        TextStyle.NARROW,   Locale.TAIWAN,  "\u6c11\u570b" },
+            { MinguoEra.BEFORE_ROC, TextStyle.FULL,     Locale.US,      "B.R.O.C." },
             { MinguoEra.ROC,        TextStyle.FULL,     Locale.US,      "Minguo" },
             { MinguoEra.BEFORE_ROC, TextStyle.FULL,     Locale.TAIWAN,  "\u6c11\u570b\u524d" },
             { MinguoEra.ROC,        TextStyle.FULL,     Locale.TAIWAN,  "\u6c11\u570b" },
-            { MinguoEra.BEFORE_ROC, TextStyle.SHORT,    Locale.US,      "Before R.O.C." },
+            { MinguoEra.BEFORE_ROC, TextStyle.SHORT,    Locale.US,      "B.R.O.C." },
             { MinguoEra.ROC,        TextStyle.SHORT,    Locale.US,      "Minguo" },
             { MinguoEra.BEFORE_ROC, TextStyle.SHORT,    Locale.TAIWAN,  "\u6c11\u570b\u524d" },
             { MinguoEra.ROC,        TextStyle.SHORT,    Locale.TAIWAN,  "\u6c11\u570b" },
-            { MinguoEra.BEFORE_ROC, TextStyle.NARROW,   Locale.US,      "Before R.O.C." },
+            { MinguoEra.BEFORE_ROC, TextStyle.NARROW,   Locale.US,      "B.R.O.C." },
             { MinguoEra.ROC,        TextStyle.NARROW,   Locale.US,      "Minguo" },
             { MinguoEra.BEFORE_ROC, TextStyle.NARROW,   Locale.TAIWAN,  "\u6c11\u570b\u524d" },
             { MinguoEra.ROC,        TextStyle.NARROW,   Locale.TAIWAN,  "\u6c11\u570b" },
diff --git a/ojluni/src/test/java/time/test/java/time/format/TestDateTimeFormatterBuilderWithLocale.java b/ojluni/src/test/java/time/test/java/time/format/TestDateTimeFormatterBuilderWithLocale.java
index a982b55..ee14792 100644
--- a/ojluni/src/test/java/time/test/java/time/format/TestDateTimeFormatterBuilderWithLocale.java
+++ b/ojluni/src/test/java/time/test/java/time/format/TestDateTimeFormatterBuilderWithLocale.java
@@ -157,11 +157,14 @@
     //-----------------------------------------------------------------------
     @DataProvider(name="localePatterns")
     Object[][] localizedDateTimePatterns() {
+        // Android-changed: Adapt for changes since old CLDR version this tests were written for.
         return new Object[][] {
             // French Locale and ISO Chronology
             {FormatStyle.FULL, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM y '\u00e0' HH:mm:ss zzzz"},
             {FormatStyle.LONG, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM y '\u00e0' HH:mm:ss z"},
-            {FormatStyle.MEDIUM, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y '\u00e0' HH:mm:ss"},
+            // Android-changed: Since ICU 68, medium format uses ',' instead of '\u00e0', to separate the date and time in French.
+            // {FormatStyle.MEDIUM, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y '\u00e0' HH:mm:ss"},
+            {FormatStyle.MEDIUM, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y, HH:mm:ss"},
             {FormatStyle.SHORT, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.FRENCH, "dd/MM/y HH:mm"},
             {FormatStyle.FULL, null, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM y"},
             {FormatStyle.LONG, null, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM y"},
@@ -187,18 +190,30 @@
             {null, FormatStyle.SHORT, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm"},
 
             // Chinese Local and Chronology
-            {FormatStyle.FULL, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE zzzz ah:mm:ss"},
-            {FormatStyle.LONG, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 z ah:mm:ss"},
-            {FormatStyle.MEDIUM, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 ah:mm:ss"},
-            {FormatStyle.SHORT, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d ah:mm"},
+            // Android-changed: Since ICU 70, use 24-hour time format
+            // {FormatStyle.FULL, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE zzzz ah:mm:ss"},
+            // {FormatStyle.LONG, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 z ah:mm:ss"},
+            // {FormatStyle.MEDIUM, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 ah:mm:ss"},
+            {FormatStyle.FULL, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE zzzz HH:mm:ss"},
+            {FormatStyle.LONG, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 z HH:mm:ss"},
+            {FormatStyle.MEDIUM, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 HH:mm:ss"},
+            // Android-changed: Since ICU 68, use single 'y' to represent year in short form like other format styles
+            // {FormatStyle.SHORT, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d ah:mm"},
+            {FormatStyle.SHORT, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy/M/d HH:mm"},
             {FormatStyle.FULL, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE"},
             {FormatStyle.LONG, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
             {FormatStyle.MEDIUM, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
-            {FormatStyle.SHORT, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d"},
-            {null, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "zzzz ah:mm:ss"},
-            {null, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "z ah:mm:ss"},
-            {null, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm:ss"},
-            {null, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm"},
+            // Android-changed: Since ICU 68, use single 'y' to represent year in short form like other format styles
+            // {FormatStyle.SHORT, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d"},
+            // {null, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "zzzz ah:mm:ss"},
+            // {null, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "z ah:mm:ss"},
+            // {null, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm:ss"},
+            // {null, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm"},
+            {FormatStyle.SHORT, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy/M/d"},
+            {null, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "zzzz HH:mm:ss"},
+            {null, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "z HH:mm:ss"},
+            {null, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "HH:mm:ss"},
+            {null, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "HH:mm"},
         };
     }
 
diff --git a/ojluni/src/test/java/time/test/java/time/format/TestDateTimeTextProviderWithLocale.java b/ojluni/src/test/java/time/test/java/time/format/TestDateTimeTextProviderWithLocale.java
index 2a426a8..7c90357 100644
--- a/ojluni/src/test/java/time/test/java/time/format/TestDateTimeTextProviderWithLocale.java
+++ b/ojluni/src/test/java/time/test/java/time/format/TestDateTimeTextProviderWithLocale.java
@@ -92,13 +92,21 @@
     @DataProvider(name = "Text")
     Object[][] data_text() {
         return new Object[][] {
-            {DAY_OF_WEEK, 1, TextStyle.SHORT, ptBR, "seg"},
-            {DAY_OF_WEEK, 2, TextStyle.SHORT, ptBR, "ter"},
-            {DAY_OF_WEEK, 3, TextStyle.SHORT, ptBR, "qua"},
-            {DAY_OF_WEEK, 4, TextStyle.SHORT, ptBR, "qui"},
-            {DAY_OF_WEEK, 5, TextStyle.SHORT, ptBR, "sex"},
-            {DAY_OF_WEEK, 6, TextStyle.SHORT, ptBR, "s\u00E1b"},
-            {DAY_OF_WEEK, 7, TextStyle.SHORT, ptBR, "dom"},
+            // Android-changed: upstream tests expect title case names for pt_BR, but CLDR has lower with dot
+            // {DAY_OF_WEEK, 1, TextStyle.SHORT, ptBR, "seg"},
+            // {DAY_OF_WEEK, 2, TextStyle.SHORT, ptBR, "ter"},
+            // {DAY_OF_WEEK, 3, TextStyle.SHORT, ptBR, "qua"},
+            // {DAY_OF_WEEK, 4, TextStyle.SHORT, ptBR, "qui"},
+            // {DAY_OF_WEEK, 5, TextStyle.SHORT, ptBR, "sex"},
+            // {DAY_OF_WEEK, 6, TextStyle.SHORT, ptBR, "s\u00E1b"},
+            // {DAY_OF_WEEK, 7, TextStyle.SHORT, ptBR, "dom"},
+            {DAY_OF_WEEK, 1, TextStyle.SHORT, ptBR, "seg."},
+            {DAY_OF_WEEK, 2, TextStyle.SHORT, ptBR, "ter."},
+            {DAY_OF_WEEK, 3, TextStyle.SHORT, ptBR, "qua."},
+            {DAY_OF_WEEK, 4, TextStyle.SHORT, ptBR, "qui."},
+            {DAY_OF_WEEK, 5, TextStyle.SHORT, ptBR, "sex."},
+            {DAY_OF_WEEK, 6, TextStyle.SHORT, ptBR, "s\u00E1b."},
+            {DAY_OF_WEEK, 7, TextStyle.SHORT, ptBR, "dom."},
 
             {DAY_OF_WEEK, 1, TextStyle.FULL, ptBR, "segunda-feira"},
             {DAY_OF_WEEK, 2, TextStyle.FULL, ptBR, "ter\u00E7a-feira"},
@@ -108,18 +116,31 @@
             {DAY_OF_WEEK, 6, TextStyle.FULL, ptBR, "s\u00E1bado"},
             {DAY_OF_WEEK, 7, TextStyle.FULL, ptBR, "domingo"},
 
-            {MONTH_OF_YEAR, 1, TextStyle.SHORT, ptBR, "jan"},
-            {MONTH_OF_YEAR, 2, TextStyle.SHORT, ptBR, "fev"},
-            {MONTH_OF_YEAR, 3, TextStyle.SHORT, ptBR, "mar"},
-            {MONTH_OF_YEAR, 4, TextStyle.SHORT, ptBR, "abr"},
-            {MONTH_OF_YEAR, 5, TextStyle.SHORT, ptBR, "mai"},
-            {MONTH_OF_YEAR, 6, TextStyle.SHORT, ptBR, "jun"},
-            {MONTH_OF_YEAR, 7, TextStyle.SHORT, ptBR, "jul"},
-            {MONTH_OF_YEAR, 8, TextStyle.SHORT, ptBR, "ago"},
-            {MONTH_OF_YEAR, 9, TextStyle.SHORT, ptBR, "set"},
-            {MONTH_OF_YEAR, 10, TextStyle.SHORT, ptBR, "out"},
-            {MONTH_OF_YEAR, 11, TextStyle.SHORT, ptBR, "nov"},
-            {MONTH_OF_YEAR, 12, TextStyle.SHORT, ptBR, "dez"},
+            // Android-changed: upstream tests expect title case names for pt_BR, but CLDR has lower with dot
+            // {MONTH_OF_YEAR, 1, TextStyle.SHORT, ptBR, "jan"},
+            // {MONTH_OF_YEAR, 2, TextStyle.SHORT, ptBR, "fev"},
+            // {MONTH_OF_YEAR, 3, TextStyle.SHORT, ptBR, "mar"},
+            // {MONTH_OF_YEAR, 4, TextStyle.SHORT, ptBR, "abr"},
+            // {MONTH_OF_YEAR, 5, TextStyle.SHORT, ptBR, "mai"},
+            // {MONTH_OF_YEAR, 6, TextStyle.SHORT, ptBR, "jun"},
+            // {MONTH_OF_YEAR, 7, TextStyle.SHORT, ptBR, "jul"},
+            // {MONTH_OF_YEAR, 8, TextStyle.SHORT, ptBR, "ago"},
+            // {MONTH_OF_YEAR, 9, TextStyle.SHORT, ptBR, "set"},
+            // {MONTH_OF_YEAR, 10, TextStyle.SHORT, ptBR, "out"},
+            // {MONTH_OF_YEAR, 11, TextStyle.SHORT, ptBR, "nov"},
+            // {MONTH_OF_YEAR, 12, TextStyle.SHORT, ptBR, "dez"},
+            {MONTH_OF_YEAR, 1, TextStyle.SHORT, ptBR, "jan."},
+            {MONTH_OF_YEAR, 2, TextStyle.SHORT, ptBR, "fev."},
+            {MONTH_OF_YEAR, 3, TextStyle.SHORT, ptBR, "mar."},
+            {MONTH_OF_YEAR, 4, TextStyle.SHORT, ptBR, "abr."},
+            {MONTH_OF_YEAR, 5, TextStyle.SHORT, ptBR, "mai."},
+            {MONTH_OF_YEAR, 6, TextStyle.SHORT, ptBR, "jun."},
+            {MONTH_OF_YEAR, 7, TextStyle.SHORT, ptBR, "jul."},
+            {MONTH_OF_YEAR, 8, TextStyle.SHORT, ptBR, "ago."},
+            {MONTH_OF_YEAR, 9, TextStyle.SHORT, ptBR, "set."},
+            {MONTH_OF_YEAR, 10, TextStyle.SHORT, ptBR, "out."},
+            {MONTH_OF_YEAR, 11, TextStyle.SHORT, ptBR, "nov."},
+            {MONTH_OF_YEAR, 12, TextStyle.SHORT, ptBR, "dez."},
 
             {MONTH_OF_YEAR, 1, TextStyle.FULL, ptBR, "janeiro"},
             {MONTH_OF_YEAR, 2, TextStyle.FULL, ptBR, "fevereiro"},
diff --git a/ojluni/src/test/java/time/test/java/time/format/TestUnicodeExtension.java b/ojluni/src/test/java/time/test/java/time/format/TestUnicodeExtension.java
index 774f078..9750964 100644
--- a/ojluni/src/test/java/time/test/java/time/format/TestUnicodeExtension.java
+++ b/ojluni/src/test/java/time/test/java/time/format/TestUnicodeExtension.java
@@ -136,7 +136,9 @@
             },
 
             {RG_GB, null, null, null, null,
-            "Thursday, 10 August 2017 at 15:15:00 Pacific Daylight Time"
+            // Android-changed: Android doesn't support "rg" extension yet.
+            // "Thursday, 10 August 2017 at 15:15:00 Pacific Daylight Time"
+            "Thursday, August 10, 2017 at 3:15:00 PM Pacific Daylight Time"
             },
 
             // DecimalStyle
@@ -195,7 +197,9 @@
             },
 
             {RG_GB, null, null, null, null,
-            "Thursday, 10 August 2017 at 15:15:00 Pacific Daylight Time"
+            // Android-changed: Android doesn't support "rg" extension yet.
+            // "Thursday, 10 August 2017 at 15:15:00 Pacific Daylight Time"
+            "Thursday, August 10, 2017 at 3:15:00 PM Pacific Daylight Time"
             },
 
             // DecimalStyle
@@ -218,13 +222,14 @@
         return new Object[][] {
             // Locale, Expected DayOfWeek,
             {Locale.US, DayOfWeek.SUNDAY},
-            {FW_SUN, DayOfWeek.SUNDAY},
-            {FW_MON, DayOfWeek.MONDAY},
-            {FW_TUE, DayOfWeek.TUESDAY},
-            {FW_WED, DayOfWeek.WEDNESDAY},
-            {FW_THU, DayOfWeek.THURSDAY},
-            {FW_FRI, DayOfWeek.FRIDAY},
-            {FW_SAT, DayOfWeek.SATURDAY},
+            // Android-removed: Android's ICU backend doesn't support "fw" unicode extension yet.
+            // {FW_SUN, DayOfWeek.SUNDAY},
+            // {FW_MON, DayOfWeek.MONDAY},
+            // {FW_TUE, DayOfWeek.TUESDAY},
+            // {FW_WED, DayOfWeek.WEDNESDAY},
+            // {FW_THU, DayOfWeek.THURSDAY},
+            // {FW_FRI, DayOfWeek.FRIDAY},
+            // {FW_SAT, DayOfWeek.SATURDAY},
 
             // invalid case
             {Locale.forLanguageTag("en-US-u-fw-xxx"), DayOfWeek.SUNDAY},
@@ -234,7 +239,8 @@
             {Locale.forLanguageTag("zh-CN-u-rg-eszzzz"), DayOfWeek.MONDAY},
 
             // "fw" and "rg".
-            {Locale.forLanguageTag("en-US-u-fw-wed-rg-gbzzzz"), DayOfWeek.WEDNESDAY},
+            // Android-removed: Android's ICU backend doesn't support "fw" unicode extension yet.
+            // {Locale.forLanguageTag("en-US-u-fw-wed-rg-gbzzzz"), DayOfWeek.WEDNESDAY},
             {Locale.forLanguageTag("en-US-u-fw-xxx-rg-gbzzzz"), DayOfWeek.MONDAY},
             {Locale.forLanguageTag("en-US-u-fw-xxx-rg-zzzz"), DayOfWeek.SUNDAY},
         };
@@ -755,7 +761,9 @@
         return new Object[][] {
             // Locale, field, Expected name,
             {Locale.US, ChronoField.AMPM_OF_DAY, "AM/PM"},
-            {RG_GB, ChronoField.AMPM_OF_DAY, "am/pm"},
+            // Android-changed: Android uses CLDR data.
+            // {RG_GB, ChronoField.AMPM_OF_DAY, "am/pm"},
+            {RG_GB, ChronoField.AMPM_OF_DAY, "AM/PM"},
         };
     }
 
@@ -838,7 +846,8 @@
         assertEquals(dtf.getZone(), ZoneId.of(expectedZone));
     }
 
-    @Test(dataProvider="getLocalizedDateTimePattern")
+    // Android-changed: Android doesn't support "rg" extension yet.
+    @Test(dataProvider="getLocalizedDateTimePattern", enabled = false)
     public void test_getLocalizedDateTimePattern(Locale l, FormatStyle s, String expectedPattern) {
         DateTimeFormatterBuilder dtfb = new DateTimeFormatterBuilder();
         assertEquals(dtfb.getLocalizedDateTimePattern(s, s, IsoChronology.INSTANCE, l),
diff --git a/ojluni/src/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java b/ojluni/src/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java
index cfcaa90..03a2f2e 100644
--- a/ojluni/src/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java
+++ b/ojluni/src/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java
@@ -218,10 +218,10 @@
             {"Australia/South",  "ACST",                  preferred_s, new Locale("en", "AU"), TextStyle.SHORT},
             // {"America/Chicago",  "CDT",                   none,        Locale.ENGLISH, TextStyle.SHORT},
             // {"Asia/Shanghai",    "CDT",                   preferred_s, Locale.ENGLISH, TextStyle.SHORT},
-            {"America/Juneau",   "AKST",                  none,      Locale.ENGLISH, TextStyle.SHORT},
-            {"America/Juneau",   "AKDT",                  none,      Locale.ENGLISH, TextStyle.SHORT},
+            // {"America/Juneau",   "AKST",                  none,      Locale.ENGLISH, TextStyle.SHORT},
+            // {"America/Juneau",   "AKDT",                  none,      Locale.ENGLISH, TextStyle.SHORT},
             {"Pacific/Honolulu", "HST",                   none,      Locale.ENGLISH, TextStyle.SHORT},
-            {"America/Halifax",  "AST",                   none,      Locale.ENGLISH, TextStyle.SHORT},
+            // {"America/Halifax",  "AST",                   none,      Locale.ENGLISH, TextStyle.SHORT},
             {"Z",                "Z",                     none,      Locale.ENGLISH, TextStyle.SHORT},
             {"Z",                "Z",                     none,      Locale.US,      TextStyle.SHORT},
             {"Z",                "Z",                     none,      Locale.CANADA,  TextStyle.SHORT},
diff --git a/ojluni/src/test/java/time/test/java/time/zone/TestZoneRules.java b/ojluni/src/test/java/time/test/java/time/zone/TestZoneRules.java
index c274139..d4041b7 100644
--- a/ojluni/src/test/java/time/test/java/time/zone/TestZoneRules.java
+++ b/ojluni/src/test/java/time/test/java/time/zone/TestZoneRules.java
@@ -107,7 +107,8 @@
         };
     }
 
-    @Test(dataProvider="negativeDST")
+    // Android-changed: Android doesn't support negative DST yet.
+    @Test(dataProvider="negativeDST", enabled = false)
     public void test_NegativeDST(ZoneId zid, LocalDate ld, ZoneOffset offset, ZoneOffset stdOffset, boolean isDST) {
         Instant i = Instant.from(ZonedDateTime.of(ld, LocalTime.MIN, zid));
         ZoneRules zr = zid.getRules();