diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java index 4fe6752be4d52..38e3b39f8cfc9 100755 --- a/core/java/android/text/format/DateFormat.java +++ b/core/java/android/text/format/DateFormat.java @@ -26,8 +26,6 @@ import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.SpannedString; -import libcore.icu.LocaleData; - import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; @@ -287,8 +285,10 @@ public class DateFormat { */ @UnsupportedAppUsage public static String getTimeFormatString(Context context, int userHandle) { - final LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale); - return is24HourFormat(context, userHandle) ? d.timeFormat_Hm : d.timeFormat_hm; + DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance( + context.getResources().getConfiguration().locale); + return is24HourFormat(context, userHandle) ? dtpg.getBestPattern("Hm") + : dtpg.getBestPattern("hm"); } /** @@ -475,7 +475,6 @@ public class DateFormat { SpannableStringBuilder s = new SpannableStringBuilder(inFormat); int count; - LocaleData localeData = LocaleData.get(Locale.getDefault()); DateFormatSymbols dfs = getIcuDateFormatSymbols(Locale.getDefault()); String[] amPm = dfs.getAmPmStrings(); @@ -506,7 +505,7 @@ public class DateFormat { break; case 'c': case 'E': - replacement = getDayOfWeekString(localeData, + replacement = getDayOfWeekString(dfs, inDate.get(Calendar.DAY_OF_WEEK), count, c); break; case 'K': // hour in am/pm (0-11) @@ -534,8 +533,7 @@ public class DateFormat { break; case 'L': case 'M': - replacement = getMonthString(localeData, - inDate.get(Calendar.MONTH), count, c); + replacement = getMonthString(dfs, inDate.get(Calendar.MONTH), count, c); break; case 'm': replacement = zeroPad(inDate.get(Calendar.MINUTE), count); @@ -568,25 +566,29 @@ public class DateFormat { } } - private static String getDayOfWeekString(LocaleData ld, int day, int count, int kind) { + private static String getDayOfWeekString(DateFormatSymbols dfs, int day, int count, int kind) { boolean standalone = (kind == 'c'); + int context = standalone ? DateFormatSymbols.STANDALONE : DateFormatSymbols.FORMAT; + final int width; if (count == 5) { - return standalone ? ld.tinyStandAloneWeekdayNames[day] : ld.tinyWeekdayNames[day]; + width = DateFormatSymbols.NARROW; } else if (count == 4) { - return standalone ? ld.longStandAloneWeekdayNames[day] : ld.longWeekdayNames[day]; + width = DateFormatSymbols.WIDE; } else { - return standalone ? ld.shortStandAloneWeekdayNames[day] : ld.shortWeekdayNames[day]; + width = DateFormatSymbols.ABBREVIATED; } + return dfs.getWeekdays(context, width)[day]; } - private static String getMonthString(LocaleData ld, int month, int count, int kind) { + private static String getMonthString(DateFormatSymbols dfs, int month, int count, int kind) { boolean standalone = (kind == 'L'); + int monthContext = standalone ? DateFormatSymbols.STANDALONE : DateFormatSymbols.FORMAT; if (count == 5) { - return standalone ? ld.tinyStandAloneMonthNames[month] : ld.tinyMonthNames[month]; + return dfs.getMonths(monthContext, DateFormatSymbols.NARROW)[month]; } else if (count == 4) { - return standalone ? ld.longStandAloneMonthNames[month] : ld.longMonthNames[month]; + return dfs.getMonths(monthContext, DateFormatSymbols.WIDE)[month]; } else if (count == 3) { - return standalone ? ld.shortStandAloneMonthNames[month] : ld.shortMonthNames[month]; + return dfs.getMonths(monthContext, DateFormatSymbols.ABBREVIATED)[month]; } else { // Calendar.JANUARY == 0, so add 1 to month. return zeroPad(month+1, count); diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java index f313faec17566..31464575186b8 100644 --- a/core/java/android/text/format/DateUtils.java +++ b/core/java/android/text/format/DateUtils.java @@ -20,6 +20,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; +import android.icu.text.DateFormatSymbols; import android.icu.text.MeasureFormat; import android.icu.text.MeasureFormat.FormatWidth; import android.icu.util.Measure; @@ -27,8 +28,6 @@ import android.icu.util.MeasureUnit; import com.android.internal.R; -import libcore.icu.LocaleData; - import java.io.IOException; import java.util.Calendar; import java.util.Date; @@ -200,17 +199,23 @@ public class DateUtils */ @Deprecated public static String getDayOfWeekString(int dayOfWeek, int abbrev) { - LocaleData d = LocaleData.get(Locale.getDefault()); - String[] names; + DateFormatSymbols dfs = DateFormatSymbols.getInstance(); + final int width; switch (abbrev) { - case LENGTH_LONG: names = d.longWeekdayNames; break; - case LENGTH_MEDIUM: names = d.shortWeekdayNames; break; - case LENGTH_SHORT: names = d.shortWeekdayNames; break; // TODO - case LENGTH_SHORTER: names = d.shortWeekdayNames; break; // TODO - case LENGTH_SHORTEST: names = d.tinyWeekdayNames; break; - default: names = d.shortWeekdayNames; break; + case LENGTH_LONG: + width = DateFormatSymbols.WIDE; + break; + case LENGTH_SHORTEST: + width = DateFormatSymbols.NARROW; + break; + case LENGTH_MEDIUM: + case LENGTH_SHORT: // TODO + case LENGTH_SHORTER: // TODO + default: + width = DateFormatSymbols.ABBREVIATED; + break; } - return names[dayOfWeek]; + return dfs.getWeekdays(DateFormatSymbols.FORMAT, width)[dayOfWeek]; } /** @@ -239,17 +244,23 @@ public class DateUtils */ @Deprecated public static String getMonthString(int month, int abbrev) { - LocaleData d = LocaleData.get(Locale.getDefault()); - String[] names; + DateFormatSymbols dfs = DateFormat.getIcuDateFormatSymbols(Locale.getDefault()); + final int width; switch (abbrev) { - case LENGTH_LONG: names = d.longMonthNames; break; - case LENGTH_MEDIUM: names = d.shortMonthNames; break; - case LENGTH_SHORT: names = d.shortMonthNames; break; - case LENGTH_SHORTER: names = d.shortMonthNames; break; - case LENGTH_SHORTEST: names = d.tinyMonthNames; break; - default: names = d.shortMonthNames; break; + case LENGTH_LONG: + width = DateFormatSymbols.WIDE; + break; + case LENGTH_SHORTEST: + width = DateFormatSymbols.NARROW; + break; + case LENGTH_MEDIUM: + case LENGTH_SHORT: + case LENGTH_SHORTER: + default: + width = DateFormatSymbols.ABBREVIATED; + break; } - return names[month]; + return dfs.getMonths(DateFormatSymbols.FORMAT, width)[month]; } /** diff --git a/core/java/android/text/format/TimeFormatter.java b/core/java/android/text/format/TimeFormatter.java index 9393f36d1b6ff..c71dfbbafd405 100644 --- a/core/java/android/text/format/TimeFormatter.java +++ b/core/java/android/text/format/TimeFormatter.java @@ -22,11 +22,10 @@ package android.text.format; import android.content.res.Resources; import android.icu.text.DateFormatSymbols; +import android.icu.text.DecimalFormatSymbols; import com.android.i18n.timezone.ZoneInfoData; -import libcore.icu.LocaleData; - import java.nio.CharBuffer; import java.time.Instant; import java.time.LocalDateTime; @@ -53,17 +52,17 @@ class TimeFormatter { private static final int DAYSPERNYEAR = 365; /** - * The Locale for which the cached LocaleData and formats have been loaded. + * The Locale for which the cached symbols and formats have been loaded. */ private static Locale sLocale; private static DateFormatSymbols sDateFormatSymbols; - private static LocaleData sLocaleData; + private static DecimalFormatSymbols sDecimalFormatSymbols; private static String sTimeOnlyFormat; private static String sDateOnlyFormat; private static String sDateTimeFormat; private final DateFormatSymbols dateFormatSymbols; - private final LocaleData localeData; + private final DecimalFormatSymbols decimalFormatSymbols; private final String dateTimeFormat; private final String timeOnlyFormat; private final String dateOnlyFormat; @@ -78,7 +77,7 @@ class TimeFormatter { if (sLocale == null || !(locale.equals(sLocale))) { sLocale = locale; sDateFormatSymbols = DateFormat.getIcuDateFormatSymbols(locale); - sLocaleData = LocaleData.get(locale); + sDecimalFormatSymbols = DecimalFormatSymbols.getInstance(locale); Resources r = Resources.getSystem(); sTimeOnlyFormat = r.getString(com.android.internal.R.string.time_of_day); @@ -87,10 +86,10 @@ class TimeFormatter { } this.dateFormatSymbols = sDateFormatSymbols; + this.decimalFormatSymbols = sDecimalFormatSymbols; this.dateTimeFormat = sDateTimeFormat; this.timeOnlyFormat = sTimeOnlyFormat; this.dateOnlyFormat = sDateOnlyFormat; - localeData = sLocaleData; } } @@ -172,12 +171,12 @@ class TimeFormatter { } private String localizeDigits(String s) { - if (localeData.zeroDigit == '0') { + if (decimalFormatSymbols.getZeroDigit() == '0') { return s; } int length = s.length(); - int offsetToLocalizedDigits = localeData.zeroDigit - '0'; + int offsetToLocalizedDigits = decimalFormatSymbols.getZeroDigit() - '0'; StringBuilder result = new StringBuilder(length); for (int i = 0; i < length; ++i) { char ch = s.charAt(i); @@ -220,35 +219,44 @@ class TimeFormatter { char currentChar = formatBuffer.get(formatBuffer.position()); switch (currentChar) { case 'A': - modifyAndAppend((wallTime.getWeekDay() < 0 - || wallTime.getWeekDay() >= DAYSPERWEEK) - ? "?" : localeData.longWeekdayNames[wallTime.getWeekDay() + 1], + modifyAndAppend( + (wallTime.getWeekDay() < 0 || wallTime.getWeekDay() >= DAYSPERWEEK) + ? "?" + : dateFormatSymbols.getWeekdays(DateFormatSymbols.FORMAT, + DateFormatSymbols.WIDE)[wallTime.getWeekDay() + 1], modifier); return false; case 'a': - modifyAndAppend((wallTime.getWeekDay() < 0 - || wallTime.getWeekDay() >= DAYSPERWEEK) - ? "?" : localeData.shortWeekdayNames[wallTime.getWeekDay() + 1], + modifyAndAppend( + (wallTime.getWeekDay() < 0 || wallTime.getWeekDay() >= DAYSPERWEEK) + ? "?" + : dateFormatSymbols.getWeekdays(DateFormatSymbols.FORMAT, + DateFormatSymbols.ABBREVIATED)[wallTime.getWeekDay() + 1], modifier); return false; case 'B': if (modifier == '-') { - modifyAndAppend((wallTime.getMonth() < 0 - || wallTime.getMonth() >= MONSPERYEAR) - ? "?" - : localeData.longStandAloneMonthNames[wallTime.getMonth()], + modifyAndAppend( + (wallTime.getMonth() < 0 || wallTime.getMonth() >= MONSPERYEAR) + ? "?" + : dateFormatSymbols.getMonths(DateFormatSymbols.STANDALONE, + DateFormatSymbols.WIDE)[wallTime.getMonth()], modifier); } else { - modifyAndAppend((wallTime.getMonth() < 0 - || wallTime.getMonth() >= MONSPERYEAR) - ? "?" : localeData.longMonthNames[wallTime.getMonth()], + modifyAndAppend( + (wallTime.getMonth() < 0 || wallTime.getMonth() >= MONSPERYEAR) + ? "?" + : dateFormatSymbols.getMonths(DateFormatSymbols.FORMAT, + DateFormatSymbols.WIDE)[wallTime.getMonth()], modifier); } return false; case 'b': case 'h': modifyAndAppend((wallTime.getMonth() < 0 || wallTime.getMonth() >= MONSPERYEAR) - ? "?" : localeData.shortMonthNames[wallTime.getMonth()], + ? "?" + : dateFormatSymbols.getMonths(DateFormatSymbols.FORMAT, + DateFormatSymbols.ABBREVIATED)[wallTime.getMonth()], modifier); return false; case 'C': diff --git a/core/java/android/widget/CalendarViewLegacyDelegate.java b/core/java/android/widget/CalendarViewLegacyDelegate.java index 1b899dbf6d03c..33e64f4d37e96 100644 --- a/core/java/android/widget/CalendarViewLegacyDelegate.java +++ b/core/java/android/widget/CalendarViewLegacyDelegate.java @@ -38,8 +38,6 @@ import android.view.ViewGroup; import com.android.internal.R; -import libcore.icu.LocaleData; - import java.util.Locale; /** @@ -264,7 +262,7 @@ class CalendarViewLegacyDelegate extends CalendarView.AbstractCalendarViewDelega mShowWeekNumber = a.getBoolean(R.styleable.CalendarView_showWeekNumber, DEFAULT_SHOW_WEEK_NUMBER); mFirstDayOfWeek = a.getInt(R.styleable.CalendarView_firstDayOfWeek, - LocaleData.get(Locale.getDefault()).firstDayOfWeek); + Calendar.getInstance().getFirstDayOfWeek()); final String minDate = a.getString(R.styleable.CalendarView_minDate); if (!CalendarView.parseDate(minDate, mMinDate)) { CalendarView.parseDate(DEFAULT_MIN_DATE, mMinDate); diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java index 67fef13d23f26..7de2bd10482f5 100644 --- a/core/java/android/widget/DayPickerView.java +++ b/core/java/android/widget/DayPickerView.java @@ -33,10 +33,6 @@ import com.android.internal.R; import com.android.internal.widget.ViewPager; import com.android.internal.widget.ViewPager.OnPageChangeListener; -import libcore.icu.LocaleData; - -import java.util.Locale; - class DayPickerView extends ViewGroup { private static final int DEFAULT_LAYOUT = R.layout.day_picker_content_material; private static final int DEFAULT_START_YEAR = 1900; @@ -86,7 +82,7 @@ class DayPickerView extends ViewGroup { attrs, a, defStyleAttr, defStyleRes); final int firstDayOfWeek = a.getInt(R.styleable.CalendarView_firstDayOfWeek, - LocaleData.get(Locale.getDefault()).firstDayOfWeek); + Calendar.getInstance().getFirstDayOfWeek()); final String minDate = a.getString(R.styleable.CalendarView_minDate); final String maxDate = a.getString(R.styleable.CalendarView_maxDate); diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java index e4a34b943657d..68ac2f684ef0c 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -34,6 +34,7 @@ import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.icu.text.DecimalFormatSymbols; import android.os.Build; import android.os.Bundle; import android.text.InputFilter; @@ -61,8 +62,6 @@ import android.view.inputmethod.InputMethodManager; import com.android.internal.R; -import libcore.icu.LocaleData; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -209,7 +208,7 @@ public class NumberPicker extends LinearLayout { } private static char getZeroDigit(Locale locale) { - return LocaleData.get(locale).zeroDigit; + return DecimalFormatSymbols.getInstance(locale).getZeroDigit(); } private java.util.Formatter createFormatter(Locale locale) { diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java index 80de6fc65f90f..8b74add8df0a0 100644 --- a/core/java/android/widget/SimpleMonthView.java +++ b/core/java/android/widget/SimpleMonthView.java @@ -27,6 +27,7 @@ import android.graphics.Paint.Align; import android.graphics.Paint.Style; import android.graphics.Rect; import android.graphics.Typeface; +import android.icu.text.DateFormatSymbols; import android.icu.text.DisplayContext; import android.icu.text.SimpleDateFormat; import android.icu.util.Calendar; @@ -49,8 +50,6 @@ import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import com.android.internal.R; import com.android.internal.widget.ExploreByTouchHelper; -import libcore.icu.LocaleData; - import java.text.NumberFormat; import java.util.Locale; @@ -193,7 +192,8 @@ class SimpleMonthView extends View { private void updateDayOfWeekLabels() { // Use tiny (e.g. single-character) weekday names from ICU. The indices // for this list correspond to Calendar days, e.g. SUNDAY is index 1. - final String[] tinyWeekdayNames = LocaleData.get(mLocale).tinyWeekdayNames; + final String[] tinyWeekdayNames = DateFormatSymbols.getInstance(mLocale) + .getWeekdays(DateFormatSymbols.FORMAT, DateFormatSymbols.NARROW); for (int i = 0; i < DAYS_IN_WEEK; i++) { mDayOfWeekLabels[i] = tinyWeekdayNames[(mWeekStart + i - 1) % DAYS_IN_WEEK + 1]; } diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java index 88a67625d615a..7804fd1f9f3c6 100644 --- a/core/java/android/widget/TextClock.java +++ b/core/java/android/widget/TextClock.java @@ -30,6 +30,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.res.TypedArray; import android.database.ContentObserver; +import android.icu.text.DateTimePatternGenerator; import android.net.Uri; import android.os.Handler; import android.os.SystemClock; @@ -43,8 +44,6 @@ import android.view.inspector.InspectableProperty; import com.android.internal.R; -import libcore.icu.LocaleData; - import java.util.Calendar; import java.util.TimeZone; @@ -259,14 +258,11 @@ public class TextClock extends TextView { } private void init() { - if (mFormat12 == null || mFormat24 == null) { - LocaleData ld = LocaleData.get(getContext().getResources().getConfiguration().locale); - if (mFormat12 == null) { - mFormat12 = ld.timeFormat_hm; - } - if (mFormat24 == null) { - mFormat24 = ld.timeFormat_Hm; - } + if (mFormat12 == null) { + mFormat12 = getBestDateTimePattern("hm"); + } + if (mFormat24 == null) { + mFormat24 = getBestDateTimePattern("Hm"); } createTime(mTimeZone); @@ -508,13 +504,11 @@ public class TextClock extends TextView { private void chooseFormat() { final boolean format24Requested = is24HourModeEnabled(); - LocaleData ld = LocaleData.get(getContext().getResources().getConfiguration().locale); - if (format24Requested) { - mFormat = abc(mFormat24, mFormat12, ld.timeFormat_Hm); + mFormat = abc(mFormat24, mFormat12, getBestDateTimePattern("Hm")); mDescFormat = abc(mDescFormat24, mDescFormat12, mFormat); } else { - mFormat = abc(mFormat12, mFormat24, ld.timeFormat_hm); + mFormat = abc(mFormat12, mFormat24, getBestDateTimePattern("hm")); mDescFormat = abc(mDescFormat12, mDescFormat24, mFormat); } @@ -527,6 +521,12 @@ public class TextClock extends TextView { } } + private String getBestDateTimePattern(String skeleton) { + DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance( + getContext().getResources().getConfiguration().locale); + return dtpg.getBestPattern(skeleton); + } + /** * Returns a if not null, else return b if not null, else return c. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java index 371de7439f8f1..3a42cd84369d6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java @@ -23,6 +23,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.res.TypedArray; import android.graphics.Rect; +import android.icu.text.DateTimePatternGenerator; import android.os.Bundle; import android.os.Handler; import android.os.Parcelable; @@ -54,8 +55,6 @@ import com.android.systemui.statusbar.policy.ConfigurationController.Configurati import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; -import libcore.icu.LocaleData; - import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Locale; @@ -384,15 +383,16 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C private final CharSequence getSmallTime() { Context context = getContext(); boolean is24 = DateFormat.is24HourFormat(context, mCurrentUserId); - LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale); + DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance( + context.getResources().getConfiguration().locale); final char MAGIC1 = '\uEF00'; final char MAGIC2 = '\uEF01'; SimpleDateFormat sdf; String format = mShowSeconds - ? is24 ? d.timeFormat_Hms : d.timeFormat_hms - : is24 ? d.timeFormat_Hm : d.timeFormat_hm; + ? is24 ? dtpg.getBestPattern("Hms") : dtpg.getBestPattern("hms") + : is24 ? dtpg.getBestPattern("Hm") : dtpg.getBestPattern("hm"); if (!format.equals(mClockFormatString)) { mContentDescriptionFormat = new SimpleDateFormat(format); /*