Merge "Remove libcore.icu.ICU usage in android.text.format.DateFormat"
This commit is contained in:
@@ -19,12 +19,12 @@ package android.text.format;
|
|||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.icu.text.DateTimePatternGenerator;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.SpannedString;
|
import android.text.SpannedString;
|
||||||
|
|
||||||
import libcore.icu.ICU;
|
|
||||||
import libcore.icu.LocaleData;
|
import libcore.icu.LocaleData;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
@@ -251,7 +251,8 @@ public class DateFormat {
|
|||||||
* @return a string pattern suitable for use with {@link java.text.SimpleDateFormat}.
|
* @return a string pattern suitable for use with {@link java.text.SimpleDateFormat}.
|
||||||
*/
|
*/
|
||||||
public static String getBestDateTimePattern(Locale locale, String skeleton) {
|
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.
|
* order returned here.
|
||||||
*/
|
*/
|
||||||
public static char[] getDateFormatOrder(Context context) {
|
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) {
|
private static String getDateFormatString(Context context) {
|
||||||
|
|||||||
@@ -34,8 +34,6 @@ import android.view.inputmethod.InputMethodManager;
|
|||||||
import android.widget.DatePicker.AbstractDatePickerDelegate;
|
import android.widget.DatePicker.AbstractDatePickerDelegate;
|
||||||
import android.widget.NumberPicker.OnValueChangeListener;
|
import android.widget.NumberPicker.OnValueChangeListener;
|
||||||
|
|
||||||
import libcore.icu.ICU;
|
|
||||||
|
|
||||||
import java.text.DateFormatSymbols;
|
import java.text.DateFormatSymbols;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
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
|
// 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.
|
// order the user's locale uses for that combination. http://b/7207103.
|
||||||
String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), "yyyyMMMdd");
|
String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), "yyyyMMMdd");
|
||||||
char[] order = ICU.getDateFormatOrder(pattern);
|
char[] order = DateFormat.getDateFormatOrder(pattern);
|
||||||
final int spinnerCount = order.length;
|
final int spinnerCount = order.length;
|
||||||
for (int i = 0; i < spinnerCount; i++) {
|
for (int i = 0; i < spinnerCount; i++) {
|
||||||
switch (order[i]) {
|
switch (order[i]) {
|
||||||
|
|||||||
@@ -16,8 +16,10 @@
|
|||||||
|
|
||||||
package android.text.format;
|
package android.text.format;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
|
|
||||||
@@ -27,6 +29,7 @@ import androidx.test.runner.AndroidJUnit4;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@Presubmit
|
@Presubmit
|
||||||
@@ -55,4 +58,71 @@ public class DateFormatTest {
|
|||||||
assertFalse(DateFormat.is24HourLocale(Locale.US));
|
assertFalse(DateFormat.is24HourLocale(Locale.US));
|
||||||
assertTrue(DateFormat.is24HourLocale(Locale.GERMANY));
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user