Merge "Remove libcore.icu.ICU usage in android.text.format.DateFormat"

This commit is contained in:
vichang
2020-07-10 10:47:38 +00:00
committed by Gerrit Code Review
3 changed files with 120 additions and 6 deletions

View File

@@ -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) {

View File

@@ -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]) {

View File

@@ -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);
}
}