Commit d502ad61 authored by Regan Hsu's avatar Regan Hsu Committed by Chromium LUCI CQ

[CrOS Settings] Add support for showing Month year in UTC.

The EOL dates listed at
https://support.google.com/chrome/a/answer/6220366?hl=en
do not provide a timezone.

However, they refer to UTC instead of a local time zone. (End of life
occurs at a single point in time).

Since users are NOT told that the time zone is in UTC, they will likely
confuse the end of life date to be in their local timezone.

If the end of life is on the first day of the month, the end of life
will show as one month sooner than the actual end of life.

This CL adds an extra parameter to base::TimeFormatMonthAndYear()
to allow for time formatting in UTC instead of the local time.

Fixed: 1126296
Change-Id: Iede26508a9a30e776225095bd6267bd2c2fe64eb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2399826
Commit-Queue: Regan Hsu <hsuregan@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#844088}
parent 417d9e70
......@@ -154,11 +154,22 @@ string16 TimeFormatShortDateAndTimeWithTimeZone(const Time& time) {
return TimeFormat(formatter.get(), time);
}
#if defined(OS_CHROMEOS)
string16 TimeFormatMonthAndYear(const Time& time,
const icu::TimeZone* time_zone) {
icu::SimpleDateFormat formatter =
CreateSimpleDateFormatter(DateFormatToString(DATE_FORMAT_YEAR_MONTH));
if (time_zone)
formatter.setTimeZone(*time_zone);
return TimeFormat(&formatter, time);
}
#else
string16 TimeFormatMonthAndYear(const Time& time) {
icu::SimpleDateFormat formatter =
CreateSimpleDateFormatter(DateFormatToString(DATE_FORMAT_YEAR_MONTH));
return TimeFormat(&formatter, time);
}
#endif // defined(OS_CHROMEOS)
string16 TimeFormatFriendlyDateAndTime(const Time& time) {
std::unique_ptr<icu::DateFormat> formatter(
......
......@@ -11,6 +11,11 @@
#include "base/compiler_specific.h"
#include "base/i18n/base_i18n_export.h"
#include "base/strings/string16.h"
#include "build/build_config.h"
#if defined(OS_CHROMEOS)
#include "third_party/icu/source/i18n/unicode/timezone.h"
#endif // defined(OS_CHROMEOS)
namespace base {
......@@ -72,8 +77,17 @@ BASE_I18N_EXPORT string16 TimeFormatShortDateNumeric(const Time& time);
// Returns a numeric date and time such as "12/13/52 2:44:30 PM".
BASE_I18N_EXPORT string16 TimeFormatShortDateAndTime(const Time& time);
#if defined(OS_CHROMEOS)
// Returns a month and year, e.g. "November 2007"
// Note: If `time_zone` is non-null, the time will be formatted in the provided
// time zone. Otherwise, it will default to local time.
BASE_I18N_EXPORT string16
TimeFormatMonthAndYear(const Time& time,
const icu::TimeZone* time_zone = nullptr);
#else
// Returns a month and year, e.g. "November 2007"
BASE_I18N_EXPORT string16 TimeFormatMonthAndYear(const Time& time);
#endif // defined(OS_CHROMEOS)
// Returns a numeric date and time with time zone such as
// "12/13/52 2:44:30 PM PST".
......
......@@ -11,6 +11,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/test/icu_test_util.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/icu/source/common/unicode/uversion.h"
#include "third_party/icu/source/i18n/unicode/calendar.h"
......@@ -203,6 +204,36 @@ TEST(TimeFormattingTest, TimeFormatTimeOfDayDE) {
kDropAmPm));
}
#if defined(OS_CHROMEOS)
TEST(TimeFormattingTest, TimeMonthYearInUTC) {
// See third_party/icu/source/data/locales/en.txt.
// The date patterns are "EEEE, MMMM d, y", "MMM d, y", and "M/d/yy".
test::ScopedRestoreICUDefaultLocale restore_locale;
i18n::SetICUDefaultLocale("en_US");
test::ScopedRestoreDefaultTimezone la_time("America/Los_Angeles");
Time time;
EXPECT_TRUE(Time::FromUTCExploded(kTestDateTimeExploded, &time));
EXPECT_EQ(
ASCIIToUTF16("April 2011"),
TimeFormatMonthAndYear(time, /*time_zone=*/icu::TimeZone::getGMT()));
EXPECT_EQ(ASCIIToUTF16("April 2011"),
TimeFormatMonthAndYear(time, /*time_zone=*/nullptr));
const Time::Exploded kDiffMonthsForDiffTzTime = {
2011, 4, 5, 1, // Fri, Apr 1, 2011 UTC = Thurs, March 31, 2011 US PDT.
0, 0, 0, 0 // 00:00:00.000 UTC = 05:00:00 previous day US PDT.
};
EXPECT_TRUE(Time::FromUTCExploded(kDiffMonthsForDiffTzTime, &time));
EXPECT_EQ(
ASCIIToUTF16("April 2011"),
TimeFormatMonthAndYear(time, /*time_zone=*/icu::TimeZone::getGMT()));
EXPECT_EQ(ASCIIToUTF16("March 2011"),
TimeFormatMonthAndYear(time, /*time_zone=*/nullptr));
}
#endif // defined(OS_CHROMEOS)
TEST(TimeFormattingTest, TimeFormatDateUS) {
// See third_party/icu/source/data/locales/en.txt.
// The date patterns are "EEEE, MMMM d, y", "MMM d, y", and "M/d/yy".
......
......@@ -46,29 +46,6 @@ base::Time SecondWarningDate(const base::Time& eol_date) {
return eol_date - base::TimeDelta::FromDays(kSecondWarningDaysInAdvance);
}
base::string16 FormatMonthAndYearWithOffset(base::Time eol_date) {
// TODO(crbug/998983): This is not the ideal way to correct months shifts.
// A follow up CL will modify base/i18n/time_formatting.h so that
// setting the time can be formatted based off UTC rather than only local.
//
// If the EOL date is on the first day of the month, then notifications with
// different month names may be shown to different users by
// base::TimeFormatMonthAndYear(), depending on their time zone. There are
// devices in Goldeneye with EOL dates on the first and last day of the month.
// Since only the month is shown, the day is set to the 15th to prevent any
// forward or backward month shifts.
constexpr int kApproxMidPointDayInMonth = 15;
base::Time adjusted_date;
base::Time::Exploded exploded;
eol_date.UTCExplode(&exploded);
exploded.day_of_month = kApproxMidPointDayInMonth;
if (!base::Time::FromUTCExploded(exploded, &adjusted_date)) {
return base::TimeFormatMonthAndYear(eol_date);
}
return base::TimeFormatMonthAndYear(adjusted_date);
}
} // namespace
// static
......@@ -150,8 +127,10 @@ void EolNotification::CreateNotification(base::Time eol_date, base::Time now) {
// Notifies user that updates will stop occurring at a month and year.
notification = ash::CreateSystemNotification(
message_center::NOTIFICATION_TYPE_SIMPLE, kEolNotificationId,
l10n_util::GetStringFUTF16(IDS_PENDING_EOL_NOTIFICATION_TITLE,
FormatMonthAndYearWithOffset(eol_date)),
l10n_util::GetStringFUTF16(
IDS_PENDING_EOL_NOTIFICATION_TITLE,
TimeFormatMonthAndYear(eol_date,
/*time_zone=*/icu::TimeZone::getGMT())),
l10n_util::GetStringFUTF16(IDS_PENDING_EOL_NOTIFICATION_MESSAGE,
ui::GetChromeOSDeviceName()),
base::string16() /* display_source */, GURL(kEolNotificationId),
......
......@@ -622,7 +622,9 @@ void AboutHandler::OnGetEndOfLifeInfo(
response.SetStringKey(
"aboutPageEndOfLifeMessage",
l10n_util::GetStringFUTF16(
eol_string_id, base::TimeFormatMonthAndYear(eol_info.eol_date),
eol_string_id,
base::TimeFormatMonthAndYear(eol_info.eol_date,
/*time_zone=*/icu::TimeZone::getGMT()),
base::ASCIIToUTF16(has_eol_passed ? chrome::kEolNotificationURL
: chrome::kAutoUpdatePolicyURL)));
} else {
......
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