summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorVictor Chang <vichang@google.com>2020-07-16 18:35:45 +0100
committerVictor Chang <vichang@google.com>2020-07-20 21:09:40 +0100
commit3a3a8ada42f4897768f08b726ccd859dc27bd84d (patch)
tree7f93feb400e83b895c052ee2c29a102c2956e306 /core/java/android
parent8ee3807a01abe811727a9507a788c31b82e9c0ee (diff)
Make a copy of DateIntervalFormat from libcore - part 2
Bug: 160606356 Test: atest FrameworksCoreTests:android.text.format Change-Id: I4c4253c707211f2a5ee0a11da107ab1dd6c4fab8
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/text/format/DateIntervalFormat.java162
-rw-r--r--core/java/android/text/format/DateUtils.java1
2 files changed, 85 insertions, 78 deletions
diff --git a/core/java/android/text/format/DateIntervalFormat.java b/core/java/android/text/format/DateIntervalFormat.java
index aafe5aa2e58a..427016d32ac2 100644
--- a/core/java/android/text/format/DateIntervalFormat.java
+++ b/core/java/android/text/format/DateIntervalFormat.java
@@ -16,103 +16,111 @@
package android.text.format;
-import android.compat.annotation.UnsupportedAppUsage;
+import static android.text.format.DateUtilsBridge.FORMAT_UTC;
+
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+
import android.icu.util.Calendar;
import android.icu.util.ULocale;
+import android.util.LruCache;
+
+import com.android.internal.annotations.VisibleForTesting;
import java.text.FieldPosition;
import java.util.TimeZone;
-import libcore.util.BasicLruCache;
-
-import static libcore.icu.DateUtilsBridge.FORMAT_UTC;
/**
- * Exposes icu4j's DateIntervalFormat.
+ * A wrapper of {@link android.icu.text.DateIntervalFormat} used by {@link DateUtilsBridge}.
*
* @hide
*/
-@libcore.api.CorePlatformApi
+@VisibleForTesting(visibility = PACKAGE)
public final class DateIntervalFormat {
- private static final BasicLruCache<String, android.icu.text.DateIntervalFormat> CACHED_FORMATTERS
- = new BasicLruCache<>(8);
+ private static final LruCache<String, android.icu.text.DateIntervalFormat> CACHED_FORMATTERS =
+ new LruCache<>(8);
- private DateIntervalFormat() {
- }
-
- // This is public DateUtils API in frameworks/base.
- @UnsupportedAppUsage
- @libcore.api.CorePlatformApi
- public static String formatDateRange(long startMs, long endMs, int flags, String olsonId) {
- if ((flags & FORMAT_UTC) != 0) {
- olsonId = "UTC";
+ private DateIntervalFormat() {
}
- // We create a java.util.TimeZone here to use libcore's data and libcore's olson ID / pseudo-tz
- // logic.
- TimeZone tz = (olsonId != null) ? TimeZone.getTimeZone(olsonId) : TimeZone.getDefault();
- android.icu.util.TimeZone icuTimeZone = DateUtilsBridge.icuTimeZone(tz);
- ULocale icuLocale = ULocale.getDefault();
- return formatDateRange(icuLocale, icuTimeZone, startMs, endMs, flags);
- }
- // This is our slightly more sensible internal API. (A truly sane replacement would take a
- // skeleton instead of int flags.)
- public static String formatDateRange(ULocale icuLocale, android.icu.util.TimeZone icuTimeZone,
- long startMs, long endMs, int flags) {
- Calendar startCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, startMs);
- Calendar endCalendar;
- if (startMs == endMs) {
- endCalendar = startCalendar;
- } else {
- endCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, endMs);
+ /**
+ * Format a date range.
+ */
+ @VisibleForTesting(visibility = PACKAGE)
+ public static String formatDateRange(long startMs, long endMs, int flags, String olsonId) {
+ if ((flags & FORMAT_UTC) != 0) {
+ olsonId = "UTC";
+ }
+ // We create a java.util.TimeZone here to use libcore's data and libcore's olson ID /
+ // pseudo-tz logic.
+ TimeZone tz = (olsonId != null) ? TimeZone.getTimeZone(olsonId) : TimeZone.getDefault();
+ android.icu.util.TimeZone icuTimeZone = DateUtilsBridge.icuTimeZone(tz);
+ ULocale icuLocale = ULocale.getDefault();
+ return formatDateRange(icuLocale, icuTimeZone, startMs, endMs, flags);
}
- // Special handling when the range ends at midnight:
- // - If we're not showing times, and the range is non-empty, we fudge the end date so we don't
- // count the day that's about to start.
- // - If we are showing times, and the range ends at exactly 00:00 of the day following its start
- // (which can be thought of as 24:00 the same day), we fudge the end date so we don't show the
- // dates --- unless the start is anything displayed as 00:00, in which case we include both
- // dates to disambiguate.
- // This is not the behavior of icu4j's DateIntervalFormat, but it's the required behavior
- // of Android's DateUtils.formatDateRange.
- if (isExactlyMidnight(endCalendar)) {
- boolean showTime =
- (flags & DateUtilsBridge.FORMAT_SHOW_TIME) == DateUtilsBridge.FORMAT_SHOW_TIME;
- boolean endsDayAfterStart = DateUtilsBridge.dayDistance(startCalendar, endCalendar) == 1;
- if ((!showTime && startMs != endMs)
- || (endsDayAfterStart
- && !DateUtilsBridge.isDisplayMidnightUsingSkeleton(startCalendar))) {
- endCalendar.add(Calendar.DAY_OF_MONTH, -1);
- }
- }
+ /**
+ * Format a date range. This is our slightly more sensible internal API.
+ * A truly sane replacement would take a skeleton instead of int flags.
+ */
+ @VisibleForTesting(visibility = PACKAGE)
+ public static String formatDateRange(ULocale icuLocale, android.icu.util.TimeZone icuTimeZone,
+ long startMs, long endMs, int flags) {
+ Calendar startCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, startMs);
+ Calendar endCalendar;
+ if (startMs == endMs) {
+ endCalendar = startCalendar;
+ } else {
+ endCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, endMs);
+ }
- String skeleton = DateUtilsBridge.toSkeleton(startCalendar, endCalendar, flags);
- synchronized (CACHED_FORMATTERS) {
- android.icu.text.DateIntervalFormat formatter =
- getFormatter(skeleton, icuLocale, icuTimeZone);
- return formatter.format(startCalendar, endCalendar, new StringBuffer(),
- new FieldPosition(0)).toString();
+ // Special handling when the range ends at midnight:
+ // - If we're not showing times, and the range is non-empty, we fudge the end date so we
+ // don't count the day that's about to start.
+ // - If we are showing times, and the range ends at exactly 00:00 of the day following
+ // its start (which can be thought of as 24:00 the same day), we fudge the end date so we
+ // don't show the dates --- unless the start is anything displayed as 00:00, in which case
+ // we include both dates to disambiguate.
+ // This is not the behavior of icu4j's DateIntervalFormat, but it's the required behavior
+ // of Android's DateUtils.formatDateRange.
+ if (isExactlyMidnight(endCalendar)) {
+ boolean showTime =
+ (flags & DateUtilsBridge.FORMAT_SHOW_TIME) == DateUtilsBridge.FORMAT_SHOW_TIME;
+ boolean endsDayAfterStart = DateUtilsBridge.dayDistance(startCalendar, endCalendar)
+ == 1;
+ if ((!showTime && startMs != endMs)
+ || (endsDayAfterStart
+ && !DateUtilsBridge.isDisplayMidnightUsingSkeleton(startCalendar))) {
+ endCalendar.add(Calendar.DAY_OF_MONTH, -1);
+ }
+ }
+
+ String skeleton = DateUtilsBridge.toSkeleton(startCalendar, endCalendar, flags);
+ synchronized (CACHED_FORMATTERS) {
+ android.icu.text.DateIntervalFormat formatter =
+ getFormatter(skeleton, icuLocale, icuTimeZone);
+ return formatter.format(startCalendar, endCalendar, new StringBuffer(),
+ new FieldPosition(0)).toString();
+ }
}
- }
- private static android.icu.text.DateIntervalFormat getFormatter(String skeleton, ULocale locale,
- android.icu.util.TimeZone icuTimeZone) {
- String key = skeleton + "\t" + locale + "\t" + icuTimeZone;
- android.icu.text.DateIntervalFormat formatter = CACHED_FORMATTERS.get(key);
- if (formatter != null) {
- return formatter;
+ private static android.icu.text.DateIntervalFormat getFormatter(String skeleton, ULocale locale,
+ android.icu.util.TimeZone icuTimeZone) {
+ String key = skeleton + "\t" + locale + "\t" + icuTimeZone;
+ android.icu.text.DateIntervalFormat formatter = CACHED_FORMATTERS.get(key);
+ if (formatter != null) {
+ return formatter;
+ }
+ formatter = android.icu.text.DateIntervalFormat.getInstance(skeleton, locale);
+ formatter.setTimeZone(icuTimeZone);
+ CACHED_FORMATTERS.put(key, formatter);
+ return formatter;
}
- formatter = android.icu.text.DateIntervalFormat.getInstance(skeleton, locale);
- formatter.setTimeZone(icuTimeZone);
- CACHED_FORMATTERS.put(key, formatter);
- return formatter;
- }
- private static boolean isExactlyMidnight(Calendar c) {
- return c.get(Calendar.HOUR_OF_DAY) == 0 &&
- c.get(Calendar.MINUTE) == 0 &&
- c.get(Calendar.SECOND) == 0 &&
- c.get(Calendar.MILLISECOND) == 0;
- }
+ private static boolean isExactlyMidnight(Calendar c) {
+ return c.get(Calendar.HOUR_OF_DAY) == 0
+ && c.get(Calendar.MINUTE) == 0
+ && c.get(Calendar.SECOND) == 0
+ && c.get(Calendar.MILLISECOND) == 0;
+ }
}
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index b0253a0af7a7..6f732cce41a9 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -27,7 +27,6 @@ import android.icu.util.MeasureUnit;
import com.android.internal.R;
-import libcore.icu.DateIntervalFormat;
import libcore.icu.LocaleData;
import java.io.IOException;