OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/common/time_format.h" | 5 #include "chrome/common/time_format.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "app/l10n_util.h" | 9 #include "app/l10n_util.h" |
| 10 #include "base/lazy_instance.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "base/scoped_ptr.h" | 12 #include "base/scoped_ptr.h" |
12 #include "base/singleton.h" | |
13 #include "base/stl_util-inl.h" | 13 #include "base/stl_util-inl.h" |
14 #include "base/string16.h" | 14 #include "base/string16.h" |
15 #include "base/time.h" | 15 #include "base/time.h" |
16 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
17 #include "grit/generated_resources.h" | 17 #include "grit/generated_resources.h" |
18 #include "unicode/datefmt.h" | 18 #include "unicode/datefmt.h" |
19 #include "unicode/locid.h" | 19 #include "unicode/locid.h" |
20 #include "unicode/plurfmt.h" | 20 #include "unicode/plurfmt.h" |
21 #include "unicode/plurrule.h" | 21 #include "unicode/plurrule.h" |
22 #include "unicode/smpdtfmt.h" | 22 #include "unicode/smpdtfmt.h" |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 BuildFormats(FORMAT_ELAPSED, &time_elapsed_formatter_); | 161 BuildFormats(FORMAT_ELAPSED, &time_elapsed_formatter_); |
162 } | 162 } |
163 ~TimeFormatter() { | 163 ~TimeFormatter() { |
164 STLDeleteContainerPointers(short_formatter_.begin(), | 164 STLDeleteContainerPointers(short_formatter_.begin(), |
165 short_formatter_.end()); | 165 short_formatter_.end()); |
166 STLDeleteContainerPointers(time_left_formatter_.begin(), | 166 STLDeleteContainerPointers(time_left_formatter_.begin(), |
167 time_left_formatter_.end()); | 167 time_left_formatter_.end()); |
168 STLDeleteContainerPointers(time_elapsed_formatter_.begin(), | 168 STLDeleteContainerPointers(time_elapsed_formatter_.begin(), |
169 time_elapsed_formatter_.end()); | 169 time_elapsed_formatter_.end()); |
170 } | 170 } |
171 friend class Singleton<TimeFormatter>; | 171 friend struct base::DefaultLazyInstanceTraits<TimeFormatter>; |
172 friend struct DefaultSingletonTraits<TimeFormatter>; | |
173 | 172 |
174 std::vector<icu::PluralFormat*> short_formatter_; | 173 std::vector<icu::PluralFormat*> short_formatter_; |
175 std::vector<icu::PluralFormat*> time_left_formatter_; | 174 std::vector<icu::PluralFormat*> time_left_formatter_; |
176 std::vector<icu::PluralFormat*> time_elapsed_formatter_; | 175 std::vector<icu::PluralFormat*> time_elapsed_formatter_; |
177 static void BuildFormats(FormatType format_type, | 176 static void BuildFormats(FormatType format_type, |
178 std::vector<icu::PluralFormat*>* time_formats); | 177 std::vector<icu::PluralFormat*>* time_formats); |
179 static icu::PluralFormat* createFallbackFormat( | 178 static icu::PluralFormat* createFallbackFormat( |
180 const icu::PluralRules& rules, int index, FormatType format_type); | 179 const icu::PluralRules& rules, int index, FormatType format_type); |
181 | 180 |
182 DISALLOW_COPY_AND_ASSIGN(TimeFormatter); | 181 DISALLOW_COPY_AND_ASSIGN(TimeFormatter); |
183 }; | 182 }; |
184 | 183 |
| 184 static base::LazyInstance<TimeFormatter> g_time_formatter( |
| 185 base::LINKER_INITIALIZED); |
| 186 |
185 void TimeFormatter::BuildFormats( | 187 void TimeFormatter::BuildFormats( |
186 FormatType format_type, std::vector<icu::PluralFormat*>* time_formats) { | 188 FormatType format_type, std::vector<icu::PluralFormat*>* time_formats) { |
187 static const icu::UnicodeString kKeywords[] = { | 189 static const icu::UnicodeString kKeywords[] = { |
188 UNICODE_STRING_SIMPLE("other"), UNICODE_STRING_SIMPLE("one"), | 190 UNICODE_STRING_SIMPLE("other"), UNICODE_STRING_SIMPLE("one"), |
189 UNICODE_STRING_SIMPLE("zero"), UNICODE_STRING_SIMPLE("two"), | 191 UNICODE_STRING_SIMPLE("zero"), UNICODE_STRING_SIMPLE("two"), |
190 UNICODE_STRING_SIMPLE("few"), UNICODE_STRING_SIMPLE("many") | 192 UNICODE_STRING_SIMPLE("few"), UNICODE_STRING_SIMPLE("many") |
191 }; | 193 }; |
192 UErrorCode err = U_ZERO_ERROR; | 194 UErrorCode err = U_ZERO_ERROR; |
193 scoped_ptr<icu::PluralRules> rules( | 195 scoped_ptr<icu::PluralRules> rules( |
194 icu::PluralRules::forLocale(icu::Locale::getDefault(), err)); | 196 icu::PluralRules::forLocale(icu::Locale::getDefault(), err)); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 if (rules.isKeyword(UNICODE_STRING_SIMPLE("one"))) { | 248 if (rules.isKeyword(UNICODE_STRING_SIMPLE("one"))) { |
247 pattern += UNICODE_STRING_SIMPLE("one{# ") + kUnits[index][0] + suffix; | 249 pattern += UNICODE_STRING_SIMPLE("one{# ") + kUnits[index][0] + suffix; |
248 } | 250 } |
249 pattern += UNICODE_STRING_SIMPLE(" other{# ") + kUnits[index][1] + suffix; | 251 pattern += UNICODE_STRING_SIMPLE(" other{# ") + kUnits[index][1] + suffix; |
250 UErrorCode err = U_ZERO_ERROR; | 252 UErrorCode err = U_ZERO_ERROR; |
251 icu::PluralFormat* format = new icu::PluralFormat(rules, pattern, err); | 253 icu::PluralFormat* format = new icu::PluralFormat(rules, pattern, err); |
252 DCHECK(U_SUCCESS(err)); | 254 DCHECK(U_SUCCESS(err)); |
253 return format; | 255 return format; |
254 } | 256 } |
255 | 257 |
256 Singleton<TimeFormatter> time_formatter; | |
257 | |
258 static string16 FormatTimeImpl(const TimeDelta& delta, FormatType format_type) { | 258 static string16 FormatTimeImpl(const TimeDelta& delta, FormatType format_type) { |
259 if (delta.ToInternalValue() < 0) { | 259 if (delta.ToInternalValue() < 0) { |
260 NOTREACHED() << "Negative duration"; | 260 NOTREACHED() << "Negative duration"; |
261 return string16(); | 261 return string16(); |
262 } | 262 } |
263 | 263 |
264 int number; | 264 int number; |
265 | 265 |
266 const std::vector<icu::PluralFormat*>& formatters = | 266 const std::vector<icu::PluralFormat*>& formatters = |
267 time_formatter->formatter(format_type); | 267 g_time_formatter.Get().formatter(format_type); |
268 | 268 |
269 UErrorCode error = U_ZERO_ERROR; | 269 UErrorCode error = U_ZERO_ERROR; |
270 icu::UnicodeString time_string; | 270 icu::UnicodeString time_string; |
271 // Less than a minute gets "X seconds left" | 271 // Less than a minute gets "X seconds left" |
272 if (delta.ToInternalValue() < Time::kMicrosecondsPerMinute) { | 272 if (delta.ToInternalValue() < Time::kMicrosecondsPerMinute) { |
273 number = static_cast<int>(delta.ToInternalValue() / | 273 number = static_cast<int>(delta.ToInternalValue() / |
274 Time::kMicrosecondsPerSecond); | 274 Time::kMicrosecondsPerSecond); |
275 time_string = formatters[0]->format(number, error); | 275 time_string = formatters[0]->format(number, error); |
276 | 276 |
277 // Less than 1 hour gets "X minutes left". | 277 // Less than 1 hour gets "X minutes left". |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 | 328 |
329 // Filter out "today" and "yesterday" | 329 // Filter out "today" and "yesterday" |
330 if (time >= midnight_today) | 330 if (time >= midnight_today) |
331 return l10n_util::GetStringUTF16(IDS_PAST_TIME_TODAY); | 331 return l10n_util::GetStringUTF16(IDS_PAST_TIME_TODAY); |
332 else if (time >= midnight_today - | 332 else if (time >= midnight_today - |
333 TimeDelta::FromMicroseconds(Time::kMicrosecondsPerDay)) | 333 TimeDelta::FromMicroseconds(Time::kMicrosecondsPerDay)) |
334 return l10n_util::GetStringUTF16(IDS_PAST_TIME_YESTERDAY); | 334 return l10n_util::GetStringUTF16(IDS_PAST_TIME_YESTERDAY); |
335 | 335 |
336 return string16(); | 336 return string16(); |
337 } | 337 } |
OLD | NEW |