Commit 2dd24c86 authored by tnagel@chromium.org's avatar tnagel@chromium.org

Fix rounding of time interval strings

Previously, text output for time intervals always was rounded
down. For example, a time interval of 1 min 59 sec was
displayed as "1 min", which was confusing users in some cases.
This CL implements rounding to nearest integer. Some example
outputs are given below.

0.49 sec --> "0 secs"
0.5  sec --> "1 sec"
59.4 sec --> "59 secs"
59.5 sec --> "1 min"
89.9 sec --> "1 min"
90.0 sec --> "2 mins"
59 min   --> "59 mins"
60 min   --> "1 hour"
89 min   --> "1 hour"
90 min   --> "2 hours"
...

BUG=338631
TEST=unit tests updated

Review URL: https://codereview.chromium.org/143633003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247948 0039d316-1c4b-4281-b951-d872f2087c98
parent 086e6d44
......@@ -282,41 +282,48 @@ icu::PluralFormat* TimeFormatter::createFallbackFormat(
}
base::string16 FormatTimeImpl(const TimeDelta& delta, FormatType format_type) {
if (delta.ToInternalValue() < 0) {
if (delta < TimeDelta::FromSeconds(0)) {
NOTREACHED() << "Negative duration";
return base::string16();
}
int number;
const std::vector<icu::PluralFormat*>& formatters =
g_time_formatter.Get().formatter(format_type);
UErrorCode error = U_ZERO_ERROR;
icu::UnicodeString time_string;
// Less than a minute gets "X seconds left"
if (delta.ToInternalValue() < Time::kMicrosecondsPerMinute) {
number = static_cast<int>(delta.ToInternalValue() /
Time::kMicrosecondsPerSecond);
time_string = formatters[0]->format(number, error);
// Less than 1 hour gets "X minutes left".
} else if (delta.ToInternalValue() < Time::kMicrosecondsPerHour) {
number = static_cast<int>(delta.ToInternalValue() /
Time::kMicrosecondsPerMinute);
time_string = formatters[1]->format(number, error);
// Less than 1 day remaining gets "X hours left"
} else if (delta.ToInternalValue() < Time::kMicrosecondsPerDay) {
number = static_cast<int>(delta.ToInternalValue() /
Time::kMicrosecondsPerHour);
time_string = formatters[2]->format(number, error);
// Anything bigger gets "X days left"
const TimeDelta one_minute(TimeDelta::FromMinutes(1));
const TimeDelta one_hour(TimeDelta::FromHours(1));
const TimeDelta one_day(TimeDelta::FromDays(1));
const TimeDelta half_second(TimeDelta::FromMilliseconds(500));
const TimeDelta half_minute(TimeDelta::FromSeconds(30));
const TimeDelta half_hour(TimeDelta::FromMinutes(30));
const TimeDelta half_day(TimeDelta::FromHours(12));
// Less than 59.5 seconds gets "X seconds left", anything larger is
// rounded to minutes.
if (delta < one_minute - half_second) {
const int seconds = static_cast<int>((delta + half_second).InSeconds());
time_string = formatters[0]->format(seconds, error);
// Less than 59.5 minutes gets "X minutes left", anything larger is
// rounded to hours.
} else if (delta < one_hour - half_minute) {
const int minutes = (delta + half_minute).InMinutes();
time_string = formatters[1]->format(minutes, error);
// Less than 23.5 hours gets "X hours left", anything larger is
// rounded to days.
} else if (delta < one_day - half_hour) {
const int hours = (delta + half_hour).InHours();
time_string = formatters[2]->format(hours, error);
// Anything bigger gets "X days left".
} else {
number = static_cast<int>(delta.ToInternalValue() /
Time::kMicrosecondsPerDay);
time_string = formatters[3]->format(number, error);
const int days = (delta + half_day).InDays();
time_string = formatters[3]->format(days, error);
}
// With the fallback added, this should never fail.
......
......@@ -28,28 +28,31 @@ void TestTimeFormats(const TimeDelta& delta, const char* expected_ascii) {
TEST(TimeFormat, FormatTime) {
const TimeDelta one_day = TimeDelta::FromDays(1);
const TimeDelta three_days = TimeDelta::FromDays(3);
const TimeDelta one_hour = TimeDelta::FromHours(1);
const TimeDelta four_hours = TimeDelta::FromHours(4);
const TimeDelta one_min = TimeDelta::FromMinutes(1);
const TimeDelta three_mins = TimeDelta::FromMinutes(3);
const TimeDelta one_sec = TimeDelta::FromSeconds(1);
const TimeDelta five_secs = TimeDelta::FromSeconds(5);
const TimeDelta twohundred_millisecs = TimeDelta::FromMilliseconds(200);
const TimeDelta one_second = TimeDelta::FromSeconds(1);
const TimeDelta one_millisecond = TimeDelta::FromMilliseconds(1);
const TimeDelta zero = TimeDelta::FromMilliseconds(0);
// TODO(jungshik) : These test only pass when the OS locale is 'en'.
// We need to add SetUp() and TearDown() to set the locale to 'en'.
TestTimeFormats(twohundred_millisecs, "0 secs");
TestTimeFormats(one_sec - twohundred_millisecs, "0 secs");
TestTimeFormats(one_sec + twohundred_millisecs, "1 sec");
TestTimeFormats(five_secs + twohundred_millisecs, "5 secs");
TestTimeFormats(one_min + five_secs, "1 min");
TestTimeFormats(three_mins + twohundred_millisecs, "3 mins");
TestTimeFormats(one_hour + five_secs, "1 hour");
TestTimeFormats(four_hours + five_secs, "4 hours");
TestTimeFormats(one_day + five_secs, "1 day");
TestTimeFormats(three_days, "3 days");
TestTimeFormats(three_days + four_hours, "3 days");
TestTimeFormats(zero, "0 secs");
TestTimeFormats(499 * one_millisecond, "0 secs");
TestTimeFormats(500 * one_millisecond, "1 sec");
TestTimeFormats(1 * one_second + 499 * one_millisecond, "1 sec");
TestTimeFormats(1 * one_second + 500 * one_millisecond, "2 secs");
TestTimeFormats(59 * one_second + 499 * one_millisecond, "59 secs");
TestTimeFormats(59 * one_second + 500 * one_millisecond, "1 min");
TestTimeFormats(1 * one_min + 30 * one_second - one_millisecond, "1 min");
TestTimeFormats(1 * one_min + 30 * one_second, "2 mins");
TestTimeFormats(59 * one_min + 30 * one_second - one_millisecond, "59 mins");
TestTimeFormats(59 * one_min + 30 * one_second, "1 hour");
TestTimeFormats(1 * one_hour + 30 * one_min - one_millisecond, "1 hour");
TestTimeFormats(1 * one_hour + 30 * one_min, "2 hours");
TestTimeFormats(23 * one_hour + 30 * one_min - one_millisecond, "23 hours");
TestTimeFormats(23 * one_hour + 30 * one_min, "1 day");
TestTimeFormats(1 * one_day + 12 * one_hour - one_millisecond, "1 day");
TestTimeFormats(1 * one_day + 12 * one_hour, "2 days");
}
// crbug.com/159388: This test fails when daylight savings time ends.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment