From 315a7c0335fb54beced23b1703c10563ce02ee82 Mon Sep 17 00:00:00 2001 From: Roozbeh Pournader Date: Mon, 17 Sep 2012 20:34:53 -0700 Subject: [PATCH 1/3] Use proper digits in formatElapsedTime and format3339 Use getZeroDigit() instead of a hard-coded '0' for formatting times using formatElapsedTime, so locales with different digits like Arabic and Persian could display the elapsed time properly. This is visible in Settings' list of running apps. Also changed android.text.format.Time's format3339 method to always use ASCII digits, irrespective of the locale. Change-Id: I731c96c21b3712ec347d9526e4ec3fe884dec276 --- core/java/android/text/format/DateUtils.java | 54 ++++++++------------ core/java/android/text/format/Time.java | 4 +- 2 files changed, 25 insertions(+), 33 deletions(-) diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java index 0babcc5e6e547..9e8c5b91b0d02 100644 --- a/core/java/android/text/format/DateUtils.java +++ b/core/java/android/text/format/DateUtils.java @@ -45,7 +45,6 @@ public class DateUtils private static final String FAST_FORMAT_HMMSS = "%1$d:%2$02d:%3$02d"; private static final String FAST_FORMAT_MMSS = "%1$02d:%2$02d"; - private static final char TIME_PADDING = '0'; private static final char TIME_SEPARATOR = ':'; @@ -648,33 +647,36 @@ public class DateUtils } } + private static void append(StringBuilder sb, long value, boolean pad, char zeroDigit) { + if (value < 10) { + if (pad) { + sb.append(zeroDigit); + } + } else { + sb.append((char) (zeroDigit + (value / 10))); + } + sb.append((char) (zeroDigit + (value % 10))); + } + /** - * Fast formatting of h:mm:ss + * Fast formatting of h:mm:ss. */ private static String formatElapsedTime(StringBuilder recycle, String format, long hours, long minutes, long seconds) { if (FAST_FORMAT_HMMSS.equals(format)) { + char zeroDigit = LocaleData.get(Locale.getDefault()).zeroDigit; + StringBuilder sb = recycle; if (sb == null) { sb = new StringBuilder(8); } else { sb.setLength(0); } - sb.append(hours); + append(sb, hours, false, zeroDigit); sb.append(TIME_SEPARATOR); - if (minutes < 10) { - sb.append(TIME_PADDING); - } else { - sb.append(toDigitChar(minutes / 10)); - } - sb.append(toDigitChar(minutes % 10)); + append(sb, minutes, true, zeroDigit); sb.append(TIME_SEPARATOR); - if (seconds < 10) { - sb.append(TIME_PADDING); - } else { - sb.append(toDigitChar(seconds / 10)); - } - sb.append(toDigitChar(seconds % 10)); + append(sb, seconds, true, zeroDigit); return sb.toString(); } else { return String.format(format, hours, minutes, seconds); @@ -682,40 +684,28 @@ public class DateUtils } /** - * Fast formatting of m:ss + * Fast formatting of mm:ss. */ private static String formatElapsedTime(StringBuilder recycle, String format, long minutes, long seconds) { if (FAST_FORMAT_MMSS.equals(format)) { + char zeroDigit = LocaleData.get(Locale.getDefault()).zeroDigit; + StringBuilder sb = recycle; if (sb == null) { sb = new StringBuilder(8); } else { sb.setLength(0); } - if (minutes < 10) { - sb.append(TIME_PADDING); - } else { - sb.append(toDigitChar(minutes / 10)); - } - sb.append(toDigitChar(minutes % 10)); + append(sb, minutes, false, zeroDigit); sb.append(TIME_SEPARATOR); - if (seconds < 10) { - sb.append(TIME_PADDING); - } else { - sb.append(toDigitChar(seconds / 10)); - } - sb.append(toDigitChar(seconds % 10)); + append(sb, seconds, true, zeroDigit); return sb.toString(); } else { return String.format(format, minutes, seconds); } } - private static char toDigitChar(long digit) { - return (char) (digit + '0'); - } - /** * Format a date / time such that if the then is on the same day as now, it shows * just the time and if it's a different day, it shows just the date. diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java index 45d5a70672eef..e2de8f2a3d5d6 100644 --- a/core/java/android/text/format/Time.java +++ b/core/java/android/text/format/Time.java @@ -151,6 +151,8 @@ public class Time { private static String sDateTimeFormat; private static String sAm; private static String sPm; + + // Referenced by native code. private static String sDateCommand = "%a %b %e %H:%M:%S %Z %Y"; /** @@ -673,7 +675,7 @@ public class Time { int minutes = (offset % 3600) / 60; int hours = offset / 3600; - return String.format("%s%s%02d:%02d", base, sign, hours, minutes); + return String.format(Locale.US, "%s%s%02d:%02d", base, sign, hours, minutes); } } From 6323b6c61775992e400c2d38981332583107c32b Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 18 Sep 2012 15:16:00 -0700 Subject: [PATCH 2/3] Use localized digits for Time formatting. This fixes the digits in places like Settings' data usage page and Calendar's drop-down, for languages such as Arabic. Bug: 6811327 Change-Id: I2dafcc342e3279937735697b3748b47fdfc8e691 --- core/java/android/text/format/Time.java | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java index e2de8f2a3d5d6..5ef86b1a5456d 100644 --- a/core/java/android/text/format/Time.java +++ b/core/java/android/text/format/Time.java @@ -151,6 +151,7 @@ public class Time { private static String sDateTimeFormat; private static String sAm; private static String sPm; + private static char sZeroDigit; // Referenced by native code. private static String sDateCommand = "%a %b %e %H:%M:%S %Z %Y"; @@ -325,6 +326,7 @@ public class Time { sAm = localeData.amPm[0]; sPm = localeData.amPm[1]; + sZeroDigit = localeData.zeroDigit; sShortMonths = localeData.shortMonthNames; sLongMonths = localeData.longMonthNames; @@ -340,12 +342,32 @@ public class Time { sLocale = locale; } - return format1(format); + String result = format1(format); + if (sZeroDigit != '0') { + result = localizeDigits(result); + } + return result; } } native private String format1(String format); + // TODO: unify this with java.util.Formatter's copy. + private String localizeDigits(String s) { + int length = s.length(); + int offsetToLocalizedDigits = sZeroDigit - '0'; + StringBuilder result = new StringBuilder(length); + for (int i = 0; i < length; ++i) { + char ch = s.charAt(i); + if (ch >= '0' && ch <= '9') { + ch += offsetToLocalizedDigits; + } + result.append(ch); + } + return result.toString(); + } + + /** * Return the current time in YYYYMMDDTHHMMSS format */ From 9ccf13cd6b7c840105fbcd6b2a8bd61d4e634653 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 18 Sep 2012 16:21:09 -0700 Subject: [PATCH 3/3] Fix formatDateRange month names for Farsi. This removes the LLLs seen in Calendar and Settings, for example. Bug: 6811327 Change-Id: I87c2ab9ee8d897171ce7ca4fe06cfa8b11d36536 --- core/java/android/text/format/DateUtils.java | 14 +++++++++++-- .../res/res/values-fa/donottranslate-cldr.xml | 20 +++++++++---------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java index 9e8c5b91b0d02..1060bd84d1f6c 100644 --- a/core/java/android/text/format/DateUtils.java +++ b/core/java/android/text/format/DateUtils.java @@ -1377,6 +1377,14 @@ public class DateUtils String endMonthDayString = isInstant ? null : endDate.format(MONTH_DAY_FORMAT); String endYearString = isInstant ? null : endDate.format(YEAR_FORMAT); + String startStandaloneMonthString = startMonthString; + String endStandaloneMonthString = endMonthString; + // We need standalone months for these strings in Persian (fa): http://b/6811327 + if (!numericDate && !abbrevMonth && Locale.getDefault().getLanguage().equals("fa")) { + startStandaloneMonthString = startDate.format("%-B"); + endStandaloneMonthString = endDate.format("%-B"); + } + if (startMonthNum != endMonthNum) { // Same year, different month. // Example: "October 28 - November 3" @@ -1397,7 +1405,8 @@ public class DateUtils startWeekDayString, startMonthString, startMonthDayString, startYearString, startTimeString, endWeekDayString, endMonthString, endMonthDayString, - endYearString, endTimeString); + endYearString, endTimeString, + startStandaloneMonthString, endStandaloneMonthString); } if (startDay != endDay) { @@ -1416,7 +1425,8 @@ public class DateUtils startWeekDayString, startMonthString, startMonthDayString, startYearString, startTimeString, endWeekDayString, endMonthString, endMonthDayString, - endYearString, endTimeString); + endYearString, endTimeString, + startStandaloneMonthString, endStandaloneMonthString); } // Same start and end day diff --git a/core/res/res/values-fa/donottranslate-cldr.xml b/core/res/res/values-fa/donottranslate-cldr.xml index b05268e804fba..402311af6eb35 100644 --- a/core/res/res/values-fa/donottranslate-cldr.xml +++ b/core/res/res/values-fa/donottranslate-cldr.xml @@ -37,22 +37,22 @@ %1$s،‏ %2$s %3$s %2$s %3$s %1$s،‏ %2$s - %3$s LLLL تا %8$s LLLL - %1$s %3$s LLLL تا %6$s %8$s LLLL - %5$s،‏ %3$s LLLL تا %10$s،‏ %8$s LLLL - %5$s،‏ %3$s LLLL تا %10$s،‏ %8$s LLLL - %5$s،‏ %1$s %3$s LLLL تا %10$s،‏ %6$s %8$s LLLL - %5$s،‏ %1$s %3$s LLLL تا %10$s،‏ %6$s %8$s LLLL + %3$s %11$s تا %8$s %12$s + %1$s %3$s %11$s تا %6$s %8$s %12$s + %5$s،‏ %3$s %11$s تا %10$s،‏ %8$s %12$s + %5$s،‏ %3$s %11$s تا %10$s،‏ %8$s %12$s + %5$s،‏ %1$s %3$s %11$s تا %10$s،‏ %6$s %8$s %12$s + %5$s،‏ %1$s %3$s %11$s تا %10$s،‏ %6$s %8$s %12$s %5$s،‏ %3$s %2$s %4$s تا %10$s،‏ %8$s %7$s %9$s %5$s،‏ %3$s %2$s %4$s تا %10$s،‏ %8$s %7$s %9$s %5$s،‏ %1$s %3$s %2$s %4$s تا %10$s،‏ %6$s %8$s %7$s %9$s %5$s،‏ %1$s %3$s %2$s %4$s تا %10$s،‏ %6$s %8$s %7$s %9$s %1$s %3$s %2$s %4$s تا %6$s %8$s %7$s %9$s - %3$s تا %8$s LLL - %1$s %3$s LLLL تا %6$s %8$s LLLL - %3$s LLL تا %8$s %2$s %9$s + %3$s تا %8$s %11$s + %1$s %3$s %11$s تا %6$s %8$s %12$s + %3$s %11$s تا %8$s %7$s %9$s %3$s تا %8$s %2$s %9$s - %1$s %3$s LLL تا %6$s %8$s %2$s %9$s + %1$s %3$s %11$s تا %6$s %8$s %7$s %9$s %b E d LLLL E d LLLL