Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6bffbf6 authored by Roozbeh Pournader's avatar Roozbeh Pournader
Browse files

Use ICU for formatting in DateUtils.formatDuration

Previously, we were using native strings. ICU has higher quality and
more comprehensive data.

Also adds parameters for specifying the format width (e.g. "2 hrs" vs
"2 hours").

Bug: 31526474
Test: adb shell am instrument -w -e class android.text.format.DateUtilsTest com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
Change-Id: I754f6c761c2ed3853046796c57ff2d86a6ccd43e
parent e70c9095
Loading
Loading
Loading
Loading
+41 −9
Original line number Diff line number Diff line
@@ -19,6 +19,10 @@ package android.text.format;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.icu.text.MeasureFormat;
import android.icu.text.MeasureFormat.FormatWidth;
import android.icu.util.Measure;
import android.icu.util.MeasureUnit;

import com.android.internal.R;

@@ -351,26 +355,54 @@ public class DateUtils
    }

    /**
     * Return given duration in a human-friendly format. For example, "4
     * minutes" or "1 second". Returns only largest meaningful unit of time,
     * Returns the given duration in a human-friendly format. For example,
     * "4 minutes" or "1 second". Returns only the largest meaningful unit of time,
     * from seconds up to hours.
     *
     * @hide
     */
    public static CharSequence formatDuration(long millis) {
        final Resources res = Resources.getSystem();
        return formatDuration(millis, LENGTH_LONG);
    }

    /**
     * Returns the given duration in a human-friendly format. For example,
     * "4 minutes" or "1 second". Returns only the largest meaningful unit of time,
     * from seconds up to hours.
     * <p>
     * You can use abbrev to specify a preference for abbreviations (but note that some
     * locales may not have abbreviations). Use LENGTH_LONG for the full spelling (e.g. "2 hours"),
     * LENGTH_SHORT for the abbreviated spelling if available (e.g. "2 hr"), and LENGTH_SHORTEST for
     * the briefest form available (e.g. "2h").
     * @hide
     */
    public static CharSequence formatDuration(long millis, int abbrev) {
        final FormatWidth width;
        switch (abbrev) {
            case LENGTH_LONG:
                width = FormatWidth.WIDE;
                break;
            case LENGTH_SHORT:
            case LENGTH_SHORTER:
            case LENGTH_MEDIUM:
                width = FormatWidth.SHORT;
                break;
            case LENGTH_SHORTEST:
                width = FormatWidth.NARROW;
                break;
            default:
                width = FormatWidth.WIDE;
        }
        final MeasureFormat formatter = MeasureFormat.getInstance(Locale.getDefault(), width);
        if (millis >= HOUR_IN_MILLIS) {
            final int hours = (int) ((millis + 1800000) / HOUR_IN_MILLIS);
            return res.getQuantityString(
                    com.android.internal.R.plurals.duration_hours, hours, hours);
            return formatter.format(new Measure(hours, MeasureUnit.HOUR));
        } else if (millis >= MINUTE_IN_MILLIS) {
            final int minutes = (int) ((millis + 30000) / MINUTE_IN_MILLIS);
            return res.getQuantityString(
                    com.android.internal.R.plurals.duration_minutes, minutes, minutes);
            return formatter.format(new Measure(minutes, MeasureUnit.MINUTE));
        } else {
            final int seconds = (int) ((millis + 500) / SECOND_IN_MILLIS);
            return res.getQuantityString(
                    com.android.internal.R.plurals.duration_seconds, seconds, seconds);
            return formatter.format(new Measure(seconds, MeasureUnit.SECOND));
        }
    }

+30 −0
Original line number Diff line number Diff line
@@ -61,6 +61,18 @@ public class DateUtilsTest extends TestCase {
        assertEquals("1 second", DateUtils.formatDuration(500));
        assertEquals("1 second", DateUtils.formatDuration(1000));
        assertEquals("2 seconds", DateUtils.formatDuration(1500));

        assertEquals("0 seconds", DateUtils.formatDuration(0, DateUtils.LENGTH_LONG));
        assertEquals("1 second", DateUtils.formatDuration(1000, DateUtils.LENGTH_LONG));
        assertEquals("2 seconds", DateUtils.formatDuration(1500, DateUtils.LENGTH_LONG));

        assertEquals("0 sec", DateUtils.formatDuration(0, DateUtils.LENGTH_SHORT));
        assertEquals("1 sec", DateUtils.formatDuration(1000, DateUtils.LENGTH_SHORT));
        assertEquals("2 sec", DateUtils.formatDuration(1500, DateUtils.LENGTH_SHORT));

        assertEquals("0s", DateUtils.formatDuration(0, DateUtils.LENGTH_SHORTEST));
        assertEquals("1s", DateUtils.formatDuration(1000, DateUtils.LENGTH_SHORTEST));
        assertEquals("2s", DateUtils.formatDuration(1500, DateUtils.LENGTH_SHORTEST));
    }

    @SmallTest
@@ -69,6 +81,15 @@ public class DateUtilsTest extends TestCase {
        assertEquals("60 seconds", DateUtils.formatDuration(59500));
        assertEquals("1 minute", DateUtils.formatDuration(60000));
        assertEquals("2 minutes", DateUtils.formatDuration(120000));

        assertEquals("1 minute", DateUtils.formatDuration(60000, DateUtils.LENGTH_LONG));
        assertEquals("2 minutes", DateUtils.formatDuration(120000, DateUtils.LENGTH_LONG));

        assertEquals("1 min", DateUtils.formatDuration(60000, DateUtils.LENGTH_SHORT));
        assertEquals("2 min", DateUtils.formatDuration(120000, DateUtils.LENGTH_SHORT));

        assertEquals("1m", DateUtils.formatDuration(60000, DateUtils.LENGTH_SHORTEST));
        assertEquals("2m", DateUtils.formatDuration(120000, DateUtils.LENGTH_SHORTEST));
    }

    @SmallTest
@@ -76,5 +97,14 @@ public class DateUtilsTest extends TestCase {
        assertEquals("59 minutes", DateUtils.formatDuration(3540000));
        assertEquals("1 hour", DateUtils.formatDuration(3600000));
        assertEquals("48 hours", DateUtils.formatDuration(172800000));

        assertEquals("1 hour", DateUtils.formatDuration(3600000, DateUtils.LENGTH_LONG));
        assertEquals("48 hours", DateUtils.formatDuration(172800000, DateUtils.LENGTH_LONG));

        assertEquals("1 hr", DateUtils.formatDuration(3600000, DateUtils.LENGTH_SHORT));
        assertEquals("48 hr", DateUtils.formatDuration(172800000, DateUtils.LENGTH_SHORT));

        assertEquals("1h", DateUtils.formatDuration(3600000, DateUtils.LENGTH_SHORTEST));
        assertEquals("48h", DateUtils.formatDuration(172800000, DateUtils.LENGTH_SHORTEST));
    }
}