Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "time_zone_impl.h"
00016
00017 #include <mutex>
00018 #include <string>
00019 #include <unordered_map>
00020 #include <utility>
00021
00022 #include "time_zone_fixed.h"
00023
00024 namespace absl {
00025 namespace time_internal {
00026 namespace cctz {
00027
00028 namespace {
00029
00030
00031 using TimeZoneImplByName =
00032 std::unordered_map<std::string, const time_zone::Impl*>;
00033 TimeZoneImplByName* time_zone_map = nullptr;
00034
00035
00036 std::mutex time_zone_mutex;
00037
00038 }
00039
00040 time_zone time_zone::Impl::UTC() {
00041 return time_zone(UTCImpl());
00042 }
00043
00044 bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) {
00045 const time_zone::Impl* const utc_impl = UTCImpl();
00046
00047
00048 auto offset = seconds::zero();
00049 if (FixedOffsetFromName(name, &offset) && offset == seconds::zero()) {
00050 *tz = time_zone(utc_impl);
00051 return true;
00052 }
00053
00054
00055
00056 {
00057 std::lock_guard<std::mutex> lock(time_zone_mutex);
00058 if (time_zone_map != nullptr) {
00059 TimeZoneImplByName::const_iterator itr = time_zone_map->find(name);
00060 if (itr != time_zone_map->end()) {
00061 *tz = time_zone(itr->second);
00062 return itr->second != utc_impl;
00063 }
00064 }
00065 }
00066
00067
00068 std::lock_guard<std::mutex> lock(time_zone_mutex);
00069 if (time_zone_map == nullptr) time_zone_map = new TimeZoneImplByName;
00070 const Impl*& impl = (*time_zone_map)[name];
00071 if (impl == nullptr) {
00072
00073 Impl* new_impl = new Impl(name);
00074 new_impl->zone_ = TimeZoneIf::Load(new_impl->name_);
00075 if (new_impl->zone_ == nullptr) {
00076 delete new_impl;
00077 impl = utc_impl;
00078 } else {
00079 impl = new_impl;
00080 }
00081 }
00082 *tz = time_zone(impl);
00083 return impl != utc_impl;
00084 }
00085
00086 void time_zone::Impl::ClearTimeZoneMapTestOnly() {
00087 std::lock_guard<std::mutex> lock(time_zone_mutex);
00088 if (time_zone_map != nullptr) {
00089
00090
00091 time_zone_map->clear();
00092 }
00093 }
00094
00095 time_zone::Impl::Impl(const std::string& name) : name_(name) {}
00096
00097 const time_zone::Impl* time_zone::Impl::UTCImpl() {
00098 static Impl* utc_impl = [] {
00099 Impl* impl = new Impl("UTC");
00100 impl->zone_ = TimeZoneIf::Load(impl->name_);
00101 return impl;
00102 }();
00103 return utc_impl;
00104 }
00105
00106 }
00107 }
00108 }