Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Side by Side Diff: ui/base/l10n/time_format.cc

Issue 147443007: Add support for localized time strings with two units, eg. "2 hours 17 minutes" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More cleanup and documentation Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/base/l10n/time_format.h" 5 #include "ui/base/l10n/time_format.h"
6 6
7 #include <vector> 7 #include <vector>
bartfab (slow) 2014/02/18 12:04:04 Nit: No longer used.
Thiemo Nagel 2014/02/19 17:08:44 Done.
8 8
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/logging.h"
bartfab (slow) 2014/02/18 12:04:04 Nit: Still used for NOTREACHED(), DCHECK() and fri
Thiemo Nagel 2014/02/19 17:08:44 Done.
11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/scoped_vector.h"
13 #include "base/stl_util.h"
14 #include "base/strings/string16.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/time/time.h" 10 #include "base/time/time.h"
17 #include "grit/ui_strings.h" 11 #include "grit/ui_strings.h"
18 #include "third_party/icu/source/common/unicode/locid.h" 12 #include "third_party/icu/source/common/unicode/unistr.h"
19 #include "third_party/icu/source/i18n/unicode/datefmt.h" 13 #include "ui/base/l10n/formatter.h"
20 #include "third_party/icu/source/i18n/unicode/plurfmt.h"
21 #include "third_party/icu/source/i18n/unicode/plurrule.h"
22 #include "third_party/icu/source/i18n/unicode/smpdtfmt.h"
23 #include "ui/base/l10n/l10n_util.h" 14 #include "ui/base/l10n/l10n_util.h"
24 #include "ui/base/l10n/l10n_util_plurals.h"
25 15
26 using base::Time; 16 using base::Time;
27 using base::TimeDelta; 17 using base::TimeDelta;
28 18
29 namespace { 19 using ui::TimeFormat;
30 20
31 static const char kFallbackFormatSuffixAgo[] = " ago}"; 21 namespace ui {
32 static const char kFallbackFormatSuffixLeft[] = " left}";
33 static const char kFallbackFormatSuffixDuration[] = "}";
34 22
35 // Contains message IDs for various time units and pluralities. 23 static base::LazyInstance<FormatterContainer> g_container =
36 struct MessageIDs {
37 // There are 4 different time units and 6 different pluralities.
38 int ids[4][6];
39 };
40
41 // Message IDs for different time formats.
42 static const MessageIDs kTimeElapsedMessageIDs = { {
43 {
44 IDS_TIME_ELAPSED_SECS_DEFAULT, IDS_TIME_ELAPSED_SEC_SINGULAR,
45 IDS_TIME_ELAPSED_SECS_ZERO, IDS_TIME_ELAPSED_SECS_TWO,
46 IDS_TIME_ELAPSED_SECS_FEW, IDS_TIME_ELAPSED_SECS_MANY
47 },
48 {
49 IDS_TIME_ELAPSED_MINS_DEFAULT, IDS_TIME_ELAPSED_MIN_SINGULAR,
50 IDS_TIME_ELAPSED_MINS_ZERO, IDS_TIME_ELAPSED_MINS_TWO,
51 IDS_TIME_ELAPSED_MINS_FEW, IDS_TIME_ELAPSED_MINS_MANY
52 },
53 {
54 IDS_TIME_ELAPSED_HOURS_DEFAULT, IDS_TIME_ELAPSED_HOUR_SINGULAR,
55 IDS_TIME_ELAPSED_HOURS_ZERO, IDS_TIME_ELAPSED_HOURS_TWO,
56 IDS_TIME_ELAPSED_HOURS_FEW, IDS_TIME_ELAPSED_HOURS_MANY
57 },
58 {
59 IDS_TIME_ELAPSED_DAYS_DEFAULT, IDS_TIME_ELAPSED_DAY_SINGULAR,
60 IDS_TIME_ELAPSED_DAYS_ZERO, IDS_TIME_ELAPSED_DAYS_TWO,
61 IDS_TIME_ELAPSED_DAYS_FEW, IDS_TIME_ELAPSED_DAYS_MANY
62 }
63 } };
64
65 static const MessageIDs kTimeRemainingMessageIDs = { {
66 {
67 IDS_TIME_REMAINING_SECS_DEFAULT, IDS_TIME_REMAINING_SEC_SINGULAR,
68 IDS_TIME_REMAINING_SECS_ZERO, IDS_TIME_REMAINING_SECS_TWO,
69 IDS_TIME_REMAINING_SECS_FEW, IDS_TIME_REMAINING_SECS_MANY
70 },
71 {
72 IDS_TIME_REMAINING_MINS_DEFAULT, IDS_TIME_REMAINING_MIN_SINGULAR,
73 IDS_TIME_REMAINING_MINS_ZERO, IDS_TIME_REMAINING_MINS_TWO,
74 IDS_TIME_REMAINING_MINS_FEW, IDS_TIME_REMAINING_MINS_MANY
75 },
76 {
77 IDS_TIME_REMAINING_HOURS_DEFAULT, IDS_TIME_REMAINING_HOUR_SINGULAR,
78 IDS_TIME_REMAINING_HOURS_ZERO, IDS_TIME_REMAINING_HOURS_TWO,
79 IDS_TIME_REMAINING_HOURS_FEW, IDS_TIME_REMAINING_HOURS_MANY
80 },
81 {
82 IDS_TIME_REMAINING_DAYS_DEFAULT, IDS_TIME_REMAINING_DAY_SINGULAR,
83 IDS_TIME_REMAINING_DAYS_ZERO, IDS_TIME_REMAINING_DAYS_TWO,
84 IDS_TIME_REMAINING_DAYS_FEW, IDS_TIME_REMAINING_DAYS_MANY
85 }
86 } };
87
88 static const MessageIDs kTimeRemainingLongMessageIDs = { {
89 {
90 IDS_TIME_REMAINING_LONG_SECS_DEFAULT, IDS_TIME_REMAINING_LONG_SEC_SINGULAR,
91 IDS_TIME_REMAINING_LONG_SECS_ZERO, IDS_TIME_REMAINING_LONG_SECS_TWO,
92 IDS_TIME_REMAINING_LONG_SECS_FEW, IDS_TIME_REMAINING_LONG_SECS_MANY
93 },
94 {
95 IDS_TIME_REMAINING_LONG_MINS_DEFAULT, IDS_TIME_REMAINING_LONG_MIN_SINGULAR,
96 IDS_TIME_REMAINING_LONG_MINS_ZERO, IDS_TIME_REMAINING_LONG_MINS_TWO,
97 IDS_TIME_REMAINING_LONG_MINS_FEW, IDS_TIME_REMAINING_LONG_MINS_MANY
98 },
99 {
100 IDS_TIME_REMAINING_HOURS_DEFAULT, IDS_TIME_REMAINING_HOUR_SINGULAR,
101 IDS_TIME_REMAINING_HOURS_ZERO, IDS_TIME_REMAINING_HOURS_TWO,
102 IDS_TIME_REMAINING_HOURS_FEW, IDS_TIME_REMAINING_HOURS_MANY
103 },
104 {
105 IDS_TIME_REMAINING_DAYS_DEFAULT, IDS_TIME_REMAINING_DAY_SINGULAR,
106 IDS_TIME_REMAINING_DAYS_ZERO, IDS_TIME_REMAINING_DAYS_TWO,
107 IDS_TIME_REMAINING_DAYS_FEW, IDS_TIME_REMAINING_DAYS_MANY
108 }
109 } };
110
111 static const MessageIDs kTimeDurationShortMessageIDs = { {
112 {
113 IDS_TIME_SECS_DEFAULT, IDS_TIME_SEC_SINGULAR, IDS_TIME_SECS_ZERO,
114 IDS_TIME_SECS_TWO, IDS_TIME_SECS_FEW, IDS_TIME_SECS_MANY
115 },
116 {
117 IDS_TIME_MINS_DEFAULT, IDS_TIME_MIN_SINGULAR, IDS_TIME_MINS_ZERO,
118 IDS_TIME_MINS_TWO, IDS_TIME_MINS_FEW, IDS_TIME_MINS_MANY
119 },
120 {
121 IDS_TIME_HOURS_DEFAULT, IDS_TIME_HOUR_SINGULAR, IDS_TIME_HOURS_ZERO,
122 IDS_TIME_HOURS_TWO, IDS_TIME_HOURS_FEW, IDS_TIME_HOURS_MANY
123 },
124 {
125 IDS_TIME_DAYS_DEFAULT, IDS_TIME_DAY_SINGULAR, IDS_TIME_DAYS_ZERO,
126 IDS_TIME_DAYS_TWO, IDS_TIME_DAYS_FEW, IDS_TIME_DAYS_MANY
127 }
128 } };
129
130 static const MessageIDs kTimeDurationLongMessageIDs = { {
131 {
132 IDS_TIME_DURATION_LONG_SECS_DEFAULT, IDS_TIME_DURATION_LONG_SEC_SINGULAR,
133 IDS_TIME_DURATION_LONG_SECS_ZERO, IDS_TIME_DURATION_LONG_SECS_TWO,
134 IDS_TIME_DURATION_LONG_SECS_FEW, IDS_TIME_DURATION_LONG_SECS_MANY
135 },
136 {
137 IDS_TIME_DURATION_LONG_MINS_DEFAULT, IDS_TIME_DURATION_LONG_MIN_SINGULAR,
138 IDS_TIME_DURATION_LONG_MINS_ZERO, IDS_TIME_DURATION_LONG_MINS_TWO,
139 IDS_TIME_DURATION_LONG_MINS_FEW, IDS_TIME_DURATION_LONG_MINS_MANY
140 },
141 {
142 IDS_TIME_HOURS_DEFAULT, IDS_TIME_HOUR_SINGULAR,
143 IDS_TIME_HOURS_ZERO, IDS_TIME_HOURS_TWO,
144 IDS_TIME_HOURS_FEW, IDS_TIME_HOURS_MANY
145 },
146 {
147 IDS_TIME_DAYS_DEFAULT, IDS_TIME_DAY_SINGULAR,
148 IDS_TIME_DAYS_ZERO, IDS_TIME_DAYS_TWO,
149 IDS_TIME_DAYS_FEW, IDS_TIME_DAYS_MANY
150 }
151 } };
152
153 // Different format types.
154 enum FormatType {
155 FORMAT_ELAPSED,
156 FORMAT_REMAINING,
157 FORMAT_REMAINING_LONG,
158 FORMAT_DURATION_SHORT,
159 FORMAT_DURATION_LONG,
160 };
161
162 class TimeFormatter {
163 public:
164 const std::vector<icu::PluralFormat*>& formatter(FormatType format_type) {
165 switch (format_type) {
166 case FORMAT_ELAPSED:
167 return time_elapsed_formatter_.get();
168 case FORMAT_REMAINING:
169 return time_left_formatter_.get();
170 case FORMAT_REMAINING_LONG:
171 return time_left_long_formatter_.get();
172 case FORMAT_DURATION_SHORT:
173 return time_duration_short_formatter_.get();
174 case FORMAT_DURATION_LONG:
175 return time_duration_long_formatter_.get();
176 default:
177 NOTREACHED();
178 return time_duration_short_formatter_.get();
179 }
180 }
181 private:
182 static const MessageIDs& GetMessageIDs(FormatType format_type) {
183 switch (format_type) {
184 case FORMAT_ELAPSED:
185 return kTimeElapsedMessageIDs;
186 case FORMAT_REMAINING:
187 return kTimeRemainingMessageIDs;
188 case FORMAT_REMAINING_LONG:
189 return kTimeRemainingLongMessageIDs;
190 case FORMAT_DURATION_SHORT:
191 return kTimeDurationShortMessageIDs;
192 case FORMAT_DURATION_LONG:
193 return kTimeDurationLongMessageIDs;
194 default:
195 NOTREACHED();
196 return kTimeDurationShortMessageIDs;
197 }
198 }
199
200 static const char* GetFallbackFormatSuffix(FormatType format_type) {
201 switch (format_type) {
202 case FORMAT_ELAPSED:
203 return kFallbackFormatSuffixAgo;
204 case FORMAT_REMAINING:
205 case FORMAT_REMAINING_LONG:
206 return kFallbackFormatSuffixLeft;
207 case FORMAT_DURATION_SHORT:
208 case FORMAT_DURATION_LONG:
209 return kFallbackFormatSuffixDuration;
210 default:
211 NOTREACHED();
212 return kFallbackFormatSuffixDuration;
213 }
214 }
215
216 TimeFormatter() {
217 BuildFormats(FORMAT_ELAPSED, &time_elapsed_formatter_);
218 BuildFormats(FORMAT_REMAINING, &time_left_formatter_);
219 BuildFormats(FORMAT_REMAINING_LONG, &time_left_long_formatter_);
220 BuildFormats(FORMAT_DURATION_SHORT, &time_duration_short_formatter_);
221 BuildFormats(FORMAT_DURATION_LONG, &time_duration_long_formatter_);
222 }
223 ~TimeFormatter() {
224 }
225 friend struct base::DefaultLazyInstanceTraits<TimeFormatter>;
226
227 ScopedVector<icu::PluralFormat> time_elapsed_formatter_;
228 ScopedVector<icu::PluralFormat> time_left_formatter_;
229 ScopedVector<icu::PluralFormat> time_left_long_formatter_;
230 ScopedVector<icu::PluralFormat> time_duration_short_formatter_;
231 ScopedVector<icu::PluralFormat> time_duration_long_formatter_;
232 static void BuildFormats(FormatType format_type,
233 ScopedVector<icu::PluralFormat>* time_formats);
234 static icu::PluralFormat* createFallbackFormat(
235 const icu::PluralRules& rules, int index, FormatType format_type);
236
237 DISALLOW_COPY_AND_ASSIGN(TimeFormatter);
238 };
239
240 static base::LazyInstance<TimeFormatter> g_time_formatter =
241 LAZY_INSTANCE_INITIALIZER; 24 LAZY_INSTANCE_INITIALIZER;
242 25
243 void TimeFormatter::BuildFormats( 26 // static
244 FormatType format_type, ScopedVector<icu::PluralFormat>* time_formats) { 27 base::string16 TimeFormat::FormatTimeImpl(const FormatterContainer& container,
245 const MessageIDs& message_ids = GetMessageIDs(format_type); 28 Type type,
246 29 Length length,
247 for (int i = 0; i < 4; ++i) { 30 int cutoff,
248 icu::UnicodeString pattern; 31 const TimeDelta& delta) {
249 std::vector<int> ids;
250 for (size_t j = 0; j < arraysize(message_ids.ids[i]); ++j) {
251 ids.push_back(message_ids.ids[i][j]);
252 }
253 scoped_ptr<icu::PluralFormat> format = l10n_util::BuildPluralFormat(ids);
254 if (format) {
255 time_formats->push_back(format.release());
256 } else {
257 scoped_ptr<icu::PluralRules> rules(l10n_util::BuildPluralRules());
258 time_formats->push_back(createFallbackFormat(*rules, i, format_type));
259 }
260 }
261 }
262
263 // Create a hard-coded fallback plural format. This will never be called
264 // unless translators make a mistake.
265 icu::PluralFormat* TimeFormatter::createFallbackFormat(
266 const icu::PluralRules& rules, int index, FormatType format_type) {
267 const icu::UnicodeString kUnits[4][2] = {
268 { UNICODE_STRING_SIMPLE("sec"), UNICODE_STRING_SIMPLE("secs") },
269 { UNICODE_STRING_SIMPLE("min"), UNICODE_STRING_SIMPLE("mins") },
270 { UNICODE_STRING_SIMPLE("hour"), UNICODE_STRING_SIMPLE("hours") },
271 { UNICODE_STRING_SIMPLE("day"), UNICODE_STRING_SIMPLE("days") }
272 };
273 icu::UnicodeString suffix(GetFallbackFormatSuffix(format_type), -1, US_INV);
274 icu::UnicodeString pattern;
275 if (rules.isKeyword(UNICODE_STRING_SIMPLE("one"))) {
276 pattern += UNICODE_STRING_SIMPLE("one{# ") + kUnits[index][0] + suffix;
277 }
278 pattern += UNICODE_STRING_SIMPLE(" other{# ") + kUnits[index][1] + suffix;
279 UErrorCode err = U_ZERO_ERROR;
280 icu::PluralFormat* format = new icu::PluralFormat(rules, pattern, err);
281 DCHECK(U_SUCCESS(err));
282 return format;
283 }
284
285 base::string16 FormatTimeImpl(const TimeDelta& delta, FormatType format_type) {
286 if (delta < TimeDelta::FromSeconds(0)) { 32 if (delta < TimeDelta::FromSeconds(0)) {
287 NOTREACHED() << "Negative duration"; 33 NOTREACHED() << "Negative duration";
288 return base::string16(); 34 return base::string16();
289 } 35 }
290 36
291 const std::vector<icu::PluralFormat*>& formatters =
292 g_time_formatter.Get().formatter(format_type);
293
294 UErrorCode error = U_ZERO_ERROR;
295 icu::UnicodeString time_string; 37 icu::UnicodeString time_string;
296 38
297 const TimeDelta one_minute(TimeDelta::FromMinutes(1)); 39 const TimeDelta one_minute(TimeDelta::FromMinutes(1));
298 const TimeDelta one_hour(TimeDelta::FromHours(1)); 40 const TimeDelta one_hour(TimeDelta::FromHours(1));
299 const TimeDelta one_day(TimeDelta::FromDays(1)); 41 const TimeDelta one_day(TimeDelta::FromDays(1));
300 42
301 const TimeDelta half_second(TimeDelta::FromMilliseconds(500)); 43 const TimeDelta half_second(TimeDelta::FromMilliseconds(500));
302 const TimeDelta half_minute(TimeDelta::FromSeconds(30)); 44 const TimeDelta half_minute(TimeDelta::FromSeconds(30));
303 const TimeDelta half_hour(TimeDelta::FromMinutes(30)); 45 const TimeDelta half_hour(TimeDelta::FromMinutes(30));
304 const TimeDelta half_day(TimeDelta::FromHours(12)); 46 const TimeDelta half_day(TimeDelta::FromHours(12));
305 47
306 // Less than 59.5 seconds gets "X seconds left", anything larger is 48 // Less than 59.5 seconds gets "X seconds left", anything larger is
bartfab (slow) 2014/02/18 12:04:04 Nit, here and below: Comments like this one go ins
Thiemo Nagel 2014/02/19 17:08:44 Done.
307 // rounded to minutes. 49 // rounded to minutes.
308 if (delta < one_minute - half_second) { 50 if (delta < one_minute - half_second) {
309 const int seconds = static_cast<int>((delta + half_second).InSeconds()); 51 int seconds = static_cast<int>((delta + half_second).InSeconds());
310 time_string = formatters[0]->format(seconds, error); 52 container.Get(type, length)->Format(Formatter::SEC, seconds, time_string);
311 53
312 // Less than 59.5 minutes gets "X minutes left", anything larger is 54 // Less than 59.5 minutes gets "X minutes left", anything larger is
313 // rounded to hours. 55 // rounded to hours.
314 } else if (delta < one_hour - half_minute) { 56 } else if (delta < one_hour - (cutoff<60 ? half_minute : half_second)) {
bartfab (slow) 2014/02/18 12:04:04 1) Please update the comment to explain where the
Thiemo Nagel 2014/02/19 17:08:44 Done.
315 const int minutes = (delta + half_minute).InMinutes(); 57 if (delta < cutoff * one_minute - half_second) {
bartfab (slow) 2014/02/18 12:04:04 Nit: Add a comment that explains what these if/els
Thiemo Nagel 2014/02/19 17:08:44 This (hopefully) is now explained in time_format.h
316 time_string = formatters[1]->format(minutes, error); 58 int minutes = (delta + half_second).InMinutes();
bartfab (slow) 2014/02/18 12:04:04 Nit: const.
Thiemo Nagel 2014/02/19 17:08:44 Done.
59 int seconds = static_cast<int>(
bartfab (slow) 2014/02/18 12:04:04 Nit 1: const. Nit 2: Would it not be simpler to do
Thiemo Nagel 2014/02/19 17:08:44 Would that not imply using exactly the kind of kno
bartfab (slow) 2014/02/20 16:31:22 I don't think TimeDelta is trying to abstract away
Thiemo Nagel 2014/02/22 21:44:09 Done.
60 (delta - TimeDelta::FromMinutes(minutes) + half_second).InSeconds());
61 container.Get(type, length)->Format(Formatter::MIN_SEC, minutes, seconds,
62 time_string);
63 } else {
64 int minutes = (delta + half_minute).InMinutes();
bartfab (slow) 2014/02/18 12:04:04 Nit: const.
Thiemo Nagel 2014/02/19 17:08:44 Done.
65 container.Get(type, length)->Format(Formatter::MIN, minutes, time_string);
66 }
317 67
318 // Less than 23.5 hours gets "X hours left", anything larger is 68 // Less than 23.5 hours gets "X hours left", anything larger is
319 // rounded to days. 69 // rounded to days.
320 } else if (delta < one_day - half_hour) { 70 } else if (delta < one_day - (cutoff<24 ? half_hour : half_minute)) {
bartfab (slow) 2014/02/18 12:04:04 1) Please update the comment to explain where the
Thiemo Nagel 2014/02/19 17:08:44 Done.
321 const int hours = (delta + half_hour).InHours(); 71 if (delta < cutoff * one_hour - half_minute) {
bartfab (slow) 2014/02/18 12:04:04 Nit: Add a comment that explains what these if/els
Thiemo Nagel 2014/02/19 17:08:44 see above
322 time_string = formatters[2]->format(hours, error); 72 int hours = (delta + half_minute).InHours();
bartfab (slow) 2014/02/18 12:04:04 Nit: const.
Thiemo Nagel 2014/02/19 17:08:44 Done.
73 int minutes =
bartfab (slow) 2014/02/18 12:04:04 Nit 1: const. Nit 2: Would it not be simpler to do
Thiemo Nagel 2014/02/19 17:08:44 see above
74 (delta - TimeDelta::FromHours(hours) + half_minute).InMinutes();
75 container.Get(type, length)->Format(Formatter::HOUR_MIN, hours, minutes,
76 time_string);
77 } else {
78 int hours = (delta + half_hour).InHours();
bartfab (slow) 2014/02/18 12:04:04 Nit: const.
Thiemo Nagel 2014/02/19 17:08:44 Done.
79 container.Get(type, length)->Format(Formatter::HOUR, hours, time_string);
80 }
323 81
324 // Anything bigger gets "X days left". 82 // Anything bigger gets "X days left".
325 } else { 83 } else {
326 const int days = (delta + half_day).InDays(); 84 if (delta < cutoff * one_day - half_hour) {
bartfab (slow) 2014/02/18 12:04:04 Nit: Add a comment that explains what these if/els
Thiemo Nagel 2014/02/19 17:08:44 see above
327 time_string = formatters[3]->format(days, error); 85 int days = (delta + half_hour).InDays();
bartfab (slow) 2014/02/18 12:04:04 Nit: const.
Thiemo Nagel 2014/02/19 17:08:44 Done.
86 int hours = (delta - TimeDelta::FromDays(days) + half_hour).InHours();
bartfab (slow) 2014/02/18 12:04:04 Nit 1: const. Nit 2: Would it not be simpler to do
Thiemo Nagel 2014/02/19 17:08:44 see above
87 container.Get(type, length)->Format(Formatter::DAY_HOUR, days, hours,
88 time_string);
89 } else {
90 int days = (delta + half_day).InDays();
bartfab (slow) 2014/02/18 12:04:04 Nit: const.
Thiemo Nagel 2014/02/19 17:08:44 Done.
91 container.Get(type, length)->Format(Formatter::DAY, days, time_string);
92 }
328 } 93 }
329 94
330 // With the fallback added, this should never fail. 95 // With the fallback added, this should never fail.
bartfab (slow) 2014/02/18 12:04:04 Nit: IIUC, this comment referred to the DCHECK() j
Thiemo Nagel 2014/02/19 17:08:44 Done.
331 DCHECK(U_SUCCESS(error));
332 int capacity = time_string.length() + 1; 96 int capacity = time_string.length() + 1;
bartfab (slow) 2014/02/18 12:04:04 Nit: const.
Thiemo Nagel 2014/02/19 17:08:44 Done.
333 DCHECK_GT(capacity, 1); 97 DCHECK_GT(capacity, 1);
334 base::string16 result; 98 base::string16 result;
99 UErrorCode error = U_ZERO_ERROR;
335 time_string.extract(static_cast<UChar*>(WriteInto(&result, capacity)), 100 time_string.extract(static_cast<UChar*>(WriteInto(&result, capacity)),
bartfab (slow) 2014/02/18 12:04:04 Nit: #include "base/strings/string_util.h"
Thiemo Nagel 2014/02/19 17:08:44 Done.
336 capacity, error); 101 capacity, error);
337 DCHECK(U_SUCCESS(error)); 102 DCHECK(U_SUCCESS(error));
338 return result; 103 return result;
339 } 104 }
340 105
341 } // namespace
342
343 namespace ui {
344
345 // static 106 // static
346 base::string16 TimeFormat::TimeElapsed(const TimeDelta& delta) { 107 base::string16 TimeFormat::Simple(TimeFormat::Type type,
347 return FormatTimeImpl(delta, FORMAT_ELAPSED); 108 TimeFormat::Length length,
109 const base::TimeDelta& delta) {
110 return Detailed(type, length, 0, delta);
bartfab (slow) 2014/02/18 12:04:04 Nit: I think it would be clearer if you just calle
Thiemo Nagel 2014/02/19 17:08:44 Obsolete now as FormatTimeImpl() has been removed.
348 } 111 }
349 112
350 // static 113 // static
351 base::string16 TimeFormat::TimeRemaining(const TimeDelta& delta) { 114 base::string16 TimeFormat::Detailed(TimeFormat::Type type,
352 return FormatTimeImpl(delta, FORMAT_REMAINING); 115 TimeFormat::Length length,
116 int cutoff,
117 const base::TimeDelta& delta) {
118 return FormatTimeImpl(g_container.Get(), type, length, cutoff, delta);
353 } 119 }
354 120
355 // static 121 // static
356 base::string16 TimeFormat::TimeRemainingLong(const TimeDelta& delta) {
357 return FormatTimeImpl(delta, FORMAT_REMAINING_LONG);
358 }
359
360 // static
361 base::string16 TimeFormat::TimeDurationShort(const TimeDelta& delta) {
362 return FormatTimeImpl(delta, FORMAT_DURATION_SHORT);
363 }
364
365 // static
366 base::string16 TimeFormat::TimeDurationLong(const TimeDelta& delta) {
367 return FormatTimeImpl(delta, FORMAT_DURATION_LONG);
368 }
369
370 // static
371 base::string16 TimeFormat::RelativeDate( 122 base::string16 TimeFormat::RelativeDate(
372 const Time& time, 123 const Time& time,
373 const Time* optional_midnight_today) { 124 const Time* optional_midnight_today) {
374 Time midnight_today = optional_midnight_today ? *optional_midnight_today : 125 Time midnight_today = optional_midnight_today ? *optional_midnight_today :
375 Time::Now().LocalMidnight(); 126 Time::Now().LocalMidnight();
376 TimeDelta day = TimeDelta::FromMicroseconds(Time::kMicrosecondsPerDay); 127 TimeDelta day = TimeDelta::FromMicroseconds(Time::kMicrosecondsPerDay);
377 Time tomorrow = midnight_today + day; 128 Time tomorrow = midnight_today + day;
378 Time yesterday = midnight_today - day; 129 Time yesterday = midnight_today - day;
379 if (time >= tomorrow) 130 if (time >= tomorrow)
380 return base::string16(); 131 return base::string16();
381 else if (time >= midnight_today) 132 else if (time >= midnight_today)
382 return l10n_util::GetStringUTF16(IDS_PAST_TIME_TODAY); 133 return l10n_util::GetStringUTF16(IDS_PAST_TIME_TODAY);
383 else if (time >= yesterday) 134 else if (time >= yesterday)
384 return l10n_util::GetStringUTF16(IDS_PAST_TIME_YESTERDAY); 135 return l10n_util::GetStringUTF16(IDS_PAST_TIME_YESTERDAY);
385 return base::string16(); 136 return base::string16();
386 } 137 }
387 138
388 } // namespace ui 139 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698