| 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 |