summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcore/java/android/text/format/DateFormat.java52
-rw-r--r--core/java/android/widget/DatePickerSpinnerDelegate.java4
-rw-r--r--core/tests/coretests/src/android/text/format/DateFormatTest.java70
3 files changed, 120 insertions, 6 deletions
diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java
index 0863a813543c..683c74737a2d 100755
--- a/core/java/android/text/format/DateFormat.java
+++ b/core/java/android/text/format/DateFormat.java
@@ -19,12 +19,12 @@ package android.text.format;
import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
+import android.icu.text.DateTimePatternGenerator;
import android.provider.Settings;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.SpannedString;
-import libcore.icu.ICU;
import libcore.icu.LocaleData;
import java.text.SimpleDateFormat;
@@ -251,7 +251,8 @@ public class DateFormat {
* @return a string pattern suitable for use with {@link java.text.SimpleDateFormat}.
*/
public static String getBestDateTimePattern(Locale locale, String skeleton) {
- return ICU.getBestDateTimePattern(skeleton, locale);
+ DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(locale);
+ return dtpg.getBestPattern(skeleton);
}
/**
@@ -333,7 +334,52 @@ public class DateFormat {
* order returned here.
*/
public static char[] getDateFormatOrder(Context context) {
- return ICU.getDateFormatOrder(getDateFormatString(context));
+ return getDateFormatOrder(getDateFormatString(context));
+ }
+
+ /**
+ * @hide Used by internal framework class {@link android.widget.DatePickerSpinnerDelegate}.
+ */
+ public static char[] getDateFormatOrder(String pattern) {
+ char[] result = new char[3];
+ int resultIndex = 0;
+ boolean sawDay = false;
+ boolean sawMonth = false;
+ boolean sawYear = false;
+
+ for (int i = 0; i < pattern.length(); ++i) {
+ char ch = pattern.charAt(i);
+ if (ch == 'd' || ch == 'L' || ch == 'M' || ch == 'y') {
+ if (ch == 'd' && !sawDay) {
+ result[resultIndex++] = 'd';
+ sawDay = true;
+ } else if ((ch == 'L' || ch == 'M') && !sawMonth) {
+ result[resultIndex++] = 'M';
+ sawMonth = true;
+ } else if ((ch == 'y') && !sawYear) {
+ result[resultIndex++] = 'y';
+ sawYear = true;
+ }
+ } else if (ch == 'G') {
+ // Ignore the era specifier, if present.
+ } else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
+ throw new IllegalArgumentException("Bad pattern character '" + ch + "' in "
+ + pattern);
+ } else if (ch == '\'') {
+ if (i < pattern.length() - 1 && pattern.charAt(i + 1) == '\'') {
+ ++i;
+ } else {
+ i = pattern.indexOf('\'', i + 1);
+ if (i == -1) {
+ throw new IllegalArgumentException("Bad quoting in " + pattern);
+ }
+ ++i;
+ }
+ } else {
+ // Ignore spaces and punctuation.
+ }
+ }
+ return result;
}
private static String getDateFormatString(Context context) {
diff --git a/core/java/android/widget/DatePickerSpinnerDelegate.java b/core/java/android/widget/DatePickerSpinnerDelegate.java
index 096e6ea52c8a..fd89b2e09131 100644
--- a/core/java/android/widget/DatePickerSpinnerDelegate.java
+++ b/core/java/android/widget/DatePickerSpinnerDelegate.java
@@ -34,8 +34,6 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.DatePicker.AbstractDatePickerDelegate;
import android.widget.NumberPicker.OnValueChangeListener;
-import libcore.icu.ICU;
-
import java.text.DateFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -459,7 +457,7 @@ class DatePickerSpinnerDelegate extends AbstractDatePickerDelegate {
// We use numeric spinners for year and day, but textual months. Ask icu4c what
// order the user's locale uses for that combination. http://b/7207103.
String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), "yyyyMMMdd");
- char[] order = ICU.getDateFormatOrder(pattern);
+ char[] order = DateFormat.getDateFormatOrder(pattern);
final int spinnerCount = order.length;
for (int i = 0; i < spinnerCount; i++) {
switch (order[i]) {
diff --git a/core/tests/coretests/src/android/text/format/DateFormatTest.java b/core/tests/coretests/src/android/text/format/DateFormatTest.java
index 5a0a84db5905..fa1d56f2e68d 100644
--- a/core/tests/coretests/src/android/text/format/DateFormatTest.java
+++ b/core/tests/coretests/src/android/text/format/DateFormatTest.java
@@ -16,8 +16,10 @@
package android.text.format;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import android.platform.test.annotations.Presubmit;
@@ -27,6 +29,7 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Arrays;
import java.util.Locale;
@Presubmit
@@ -55,4 +58,71 @@ public class DateFormatTest {
assertFalse(DateFormat.is24HourLocale(Locale.US));
assertTrue(DateFormat.is24HourLocale(Locale.GERMANY));
}
+
+ @Test
+ public void testGetDateFormatOrder() {
+ // lv and fa use differing orders depending on whether you're using numeric or
+ // textual months.
+ Locale lv = new Locale("lv");
+ assertEquals("[d, M, y]", Arrays.toString(DateFormat.getDateFormatOrder(
+ best(lv, "yyyy-M-dd"))));
+ assertEquals("[y, d, M]", Arrays.toString(DateFormat.getDateFormatOrder(
+ best(lv, "yyyy-MMM-dd"))));
+ assertEquals("[d, M, \u0000]", Arrays.toString(DateFormat.getDateFormatOrder(
+ best(lv, "MMM-dd"))));
+ Locale fa = new Locale("fa");
+ assertEquals("[y, M, d]", Arrays.toString(DateFormat.getDateFormatOrder(
+ best(fa, "yyyy-M-dd"))));
+ assertEquals("[d, M, y]", Arrays.toString(DateFormat.getDateFormatOrder(
+ best(fa, "yyyy-MMM-dd"))));
+ assertEquals("[d, M, \u0000]", Arrays.toString(DateFormat.getDateFormatOrder(
+ best(fa, "MMM-dd"))));
+
+ // English differs on each side of the Atlantic.
+ Locale enUS = Locale.US;
+ assertEquals("[M, d, y]", Arrays.toString(DateFormat.getDateFormatOrder(
+ best(enUS, "yyyy-M-dd"))));
+ assertEquals("[M, d, y]", Arrays.toString(DateFormat.getDateFormatOrder(
+ best(enUS, "yyyy-MMM-dd"))));
+ assertEquals("[M, d, \u0000]", Arrays.toString(DateFormat.getDateFormatOrder(
+ best(enUS, "MMM-dd"))));
+ Locale enGB = Locale.UK;
+ assertEquals("[d, M, y]", Arrays.toString(DateFormat.getDateFormatOrder(
+ best(enGB, "yyyy-M-dd"))));
+ assertEquals("[d, M, y]", Arrays.toString(DateFormat.getDateFormatOrder(
+ best(enGB, "yyyy-MMM-dd"))));
+ assertEquals("[d, M, \u0000]", Arrays.toString(DateFormat.getDateFormatOrder(
+ best(enGB, "MMM-dd"))));
+
+ assertEquals("[y, M, d]", Arrays.toString(DateFormat.getDateFormatOrder(
+ "yyyy - 'why' '' 'ddd' MMM-dd")));
+
+ try {
+ DateFormat.getDateFormatOrder("the quick brown fox jumped over the lazy dog");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ DateFormat.getDateFormatOrder("'");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ DateFormat.getDateFormatOrder("yyyy'");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ DateFormat.getDateFormatOrder("yyyy'MMM");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ private static String best(Locale l, String skeleton) {
+ return DateFormat.getBestDateTimePattern(l, skeleton);
+ }
}