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

Unified Diff: src/i18n.cc

Issue 2724373002: [date] Add ICU backend for timezone info behind a flag (Closed)
Patch Set: Don't leak the icu::TimeZone* Created 3 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 side-by-side diff with in-line comments
Download patch
« src/i18n.h ('K') | « src/i18n.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/i18n.cc
diff --git a/src/i18n.cc b/src/i18n.cc
index d2245ef34a9a319a53b4cf4b4ea05ec095fef2d5..30d649e45c95977047b7092034b0c80b62518e78 100644
--- a/src/i18n.cc
+++ b/src/i18n.cc
@@ -899,5 +899,87 @@ void V8BreakIterator::DeleteBreakIterator(
GlobalHandles::Destroy(reinterpret_cast<Object**>(data.GetParameter()));
}
+ICUTimezoneCache::ICUTimezoneCache() { Clear(); }
jgruber 2017/03/03 08:35:29 I'm surprised this doesn't fail. Clear() deletes t
Dan Ehrenberg 2017/03/03 13:20:27 Wow, not sure how I got this so wrong; I guess I s
+
+ICUTimezoneCache::~ICUTimezoneCache() { Clear(); }
+
+const char* ICUTimezoneCache::LocalTimezone(double time_ms) {
+ bool is_dst = DaylightSavingsOffset(time_ms) != 0;
+ char* name = is_dst ? dst_timezone_name_ : timezone_name_;
jgruber 2017/03/03 08:35:29 The cache is never filled, not sure if that's on p
Dan Ehrenberg 2017/03/03 13:20:27 What do you mean? Why is it never filled? I though
jgruber 2017/03/03 13:29:08 Yup you're right. Sorry, my mistake.
+ if (name[0] == '\0') {
+ icu::UnicodeString result;
+ GetTimeZone()->getDisplayName(is_dst, icu::TimeZone::SHORT, result);
+
+ // With the SHORT format and the default locale, the result should be of
+ // the form PST or CET, short and within ASCII range.
+ int32_t length = result.length();
+ CHECK(length < kMaxTimezoneChars);
+ for (int32_t i = 0; i < length; i++) {
+ UChar ch = result[i];
+ CHECK(ch == static_cast<UChar>(static_cast<char>(ch)));
+ name[i] = static_cast<char>(ch);
+ }
+ name[length] = '\0';
+ }
+ return const_cast<const char*>(name);
+}
+
+icu::TimeZone* ICUTimezoneCache::GetTimeZone() {
+ if (timezone_ == nullptr) {
+ timezone_ = icu::TimeZone::createDefault();
+ }
+ return timezone_;
+}
+
+bool ICUTimezoneCache::GetOffsets(double time_ms, int32_t* raw_offset,
+ int32_t* dst_offset) {
+ UErrorCode status = U_ZERO_ERROR;
+ GetTimeZone()->getOffset(time_ms, false, *raw_offset, *dst_offset, status);
+ if (!U_SUCCESS(status)) return false;
jgruber 2017/03/03 08:35:29 Nit: return U_SUCCESS(status)
Dan Ehrenberg 2017/03/03 13:20:27 Done, but I would be interested in more feedback h
+ return true;
+}
+
+double ICUTimezoneCache::DaylightSavingsOffset(double time_ms) {
+ int32_t raw_offset, dst_offset;
+ if (!GetOffsets(time_ms, &raw_offset, &dst_offset)) return 0;
+ return dst_offset;
+}
+
+double ICUTimezoneCache::LocalTimeOffset() {
+ int32_t raw_offset, dst_offset;
+ if (!GetOffsets(icu::Calendar::getNow(), &raw_offset, &dst_offset)) return 0;
+ return raw_offset;
+}
+
+void ICUTimezoneCache::Clear() {
+ delete timezone_;
+ timezone_ = nullptr;
+ timezone_name_[0] = '\0';
+ dst_timezone_name_[0] = '\0';
+}
+
+ICUOSTimezoneCache::ICUOSTimezoneCache() : os_tz_cache_(nullptr) {}
+
+ICUOSTimezoneCache::~ICUOSTimezoneCache() { delete os_tz_cache_; }
+
+const char* ICUOSTimezoneCache::LocalTimezone(double time_ms) {
+ const char* result = ICUTimezoneCache::LocalTimezone(time_ms);
+ // ICU often returns timezones which are not as descriptive as they
+ // could be, e.g., GMT+1 for Europe/Madrid when in en_US. When a timezone
+ // starts with GMT, call out to the OS to get the 'real' name.
ulan 2017/03/03 13:20:27 This seems hacky as it breaks the "cache" semantic
Dan Ehrenberg 2017/03/03 15:06:54 I agree that it's hacky, but I'm not sure we'll ge
+ if (result[0] == 'G' && result[1] == 'M' && result[2] == 'T') {
jgruber 2017/03/03 08:35:29 Nit: Another option would be to use strncmp.
Dan Ehrenberg 2017/03/03 13:20:27 Done.
+ if (os_tz_cache_ == nullptr) {
+ os_tz_cache_ = base::OS::CreateTimezoneCache();
+ }
+ return os_tz_cache_->LocalTimezone(time_ms);
+ }
+ return result;
+}
+
+void ICUOSTimezoneCache::Clear() {
+ ICUTimezoneCache::Clear();
+ if (os_tz_cache_) os_tz_cache_->Clear();
+}
+
} // namespace internal
} // namespace v8
« src/i18n.h ('K') | « src/i18n.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698