Merge "Implement "fw" extension support for WeekFields.of API" am: a0f22cb7bb am: cf727fb33e

Original change: https://android-review.googlesource.com/c/platform/libcore/+/2057628

Change-Id: I0d1ed518eba01c08842f751f6e8b810e0646f51a
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/ojluni/src/main/java/java/time/temporal/WeekFields.java b/ojluni/src/main/java/java/time/temporal/WeekFields.java
index 579bc92..fc92343 100644
--- a/ojluni/src/main/java/java/time/temporal/WeekFields.java
+++ b/ojluni/src/main/java/java/time/temporal/WeekFields.java
@@ -282,11 +282,16 @@
     private final transient TemporalField weekBasedYear = ComputedDayOfField.ofWeekBasedYearField(this);
 
     //-----------------------------------------------------------------------
-    // Android-changed: Remove "fw" and "rg" support in the javadoc. See http://b/228322300.
+    // Android-changed: Remove "rg" support in the javadoc. See http://b/228322300.
+    // Android-changed: Support the "fw" extension since Android 13. See http://b/228322300.
     /**
      * Obtains an instance of {@code WeekFields} appropriate for a locale.
      * <p>
      * This will look up appropriate values from the provider of localization data.
+     * Since Android 13, if the locale contains "fw" (First day of week)
+     * <a href="../../util/Locale.html#def_locale_extension">
+     * Unicode extensions</a>, returned instance will reflect the values specified with
+     * those extensions.
      *
      * @param locale  the locale to use, not null
      * @return the week-definition, not null
@@ -294,19 +299,49 @@
     public static WeekFields of(Locale locale) {
         Objects.requireNonNull(locale, "locale");
 
-        // Android-changed: get Week data from ICU4J
-        /*
-        int calDow = CalendarDataUtility.retrieveFirstDayOfWeek(locale);
-        DayOfWeek dow = DayOfWeek.SUNDAY.plus(calDow - 1);
-        int minDays = CalendarDataUtility.retrieveMinimalDaysInFirstWeek(locale);
-        return WeekFields.of(dow, minDays);
-         */
+        // Android-changed: Obtain week data from ICU4J.
+        // int calDow = CalendarDataUtility.retrieveFirstDayOfWeek(locale);
         Calendar calendar = Calendar.getInstance(locale);
         Calendar.WeekData weekData = calendar.getWeekData();
-        DayOfWeek dow = DayOfWeek.SUNDAY.plus(weekData.firstDayOfWeek - 1);
-        return WeekFields.of(dow, weekData.minimalDaysInFirstWeek);
+        int calDow = retrieveFirstDayOfWeek(locale, weekData);
+        DayOfWeek dow = DayOfWeek.SUNDAY.plus(calDow - 1);
+        // Android-changed: Obtain minimal days from ICU4J.
+        // int minDays = CalendarDataUtility.retrieveMinimalDaysInFirstWeek(locale);
+        int minDays = weekData.minimalDaysInFirstWeek;
+        return WeekFields.of(dow, minDays);
     }
 
+    // BEGIN Android-added: Extra method needed to support "fw" the Unicode extension.
+    // A modified version of the upstream CalendarDataUtility.retrieveFirstDayOfWeek() but with
+    // ICU provider.
+    private static int retrieveFirstDayOfWeek(Locale locale, Calendar.WeekData icuWeekData) {
+        // Look for the Unicode Extension in the locale parameter
+        if (locale.hasExtensions()) {
+            String fw = locale.getUnicodeLocaleType("fw");
+            if (fw != null) {
+                switch (fw.toLowerCase(Locale.ROOT)) {
+                    case "mon":
+                        return Calendar.MONDAY;
+                    case "tue":
+                        return Calendar.TUESDAY;
+                    case "wed":
+                        return Calendar.WEDNESDAY;
+                    case "thu":
+                        return Calendar.THURSDAY;
+                    case "fri":
+                        return Calendar.FRIDAY;
+                    case "sat":
+                        return Calendar.SATURDAY;
+                    case "sun":
+                        return Calendar.SUNDAY;
+                }
+            }
+        }
+
+        return icuWeekData.firstDayOfWeek;
+    }
+    // END Android-added: Extra method needed to support "fw" the Unicode extension.
+
     /**
      * Obtains an instance of {@code WeekFields} from the first day-of-week and minimal days.
      * <p>
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 9750964..4b71f06 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
@@ -222,14 +222,13 @@
         return new Object[][] {
             // Locale, Expected DayOfWeek,
             {Locale.US, DayOfWeek.SUNDAY},
-            // 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},
+            {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},
@@ -239,8 +238,7 @@
             {Locale.forLanguageTag("zh-CN-u-rg-eszzzz"), DayOfWeek.MONDAY},
 
             // "fw" and "rg".
-            // 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-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},
         };