AceTime  1.3
Date and time classes for Arduino that support timezones from the TZ Database, and a system clock that can synchronize from an NTP server or an RTC chip.
ZoneManager.h
1 /*
2  * MIT License
3  * Copyright (c) 2019 Brian T. Park
4  */
5 
6 #ifndef ACE_TIME_ZONE_MANAGER_H
7 #define ACE_TIME_ZONE_MANAGER_H
8 
9 #include "ZoneProcessorCache.h"
10 #include "ZoneRegistrar.h"
11 #include "TimeZoneData.h"
12 #include "TimeZone.h"
13 
14 namespace ace_time {
15 
24 class ZoneManager {
25  public:
27  static const uint16_t kInvalidIndex = 0xffff;
28 
32  virtual TimeZone createForZoneName(const char* name) = 0;
33 
35  virtual TimeZone createForZoneId(uint32_t id) = 0;
36 
41  virtual TimeZone createForZoneIndex(uint16_t index) = 0;
42 
49  virtual TimeZone createForTimeZoneData(const TimeZoneData& d) = 0;
50 
55  virtual uint16_t indexForZoneName(const char* name) const = 0;
56 
61  virtual uint16_t indexForZoneId(uint32_t id) const = 0;
62 
64  virtual uint16_t registrySize() const = 0;
65 };
66 
77  public:
78 
79  TimeZone createForZoneName(const char* /*name*/) override {
80  return TimeZone::forError();
81  }
82 
83  TimeZone createForZoneId(uint32_t /*id*/) override {
84  return TimeZone::forError();
85  }
86 
87  TimeZone createForZoneIndex(uint16_t /*index*/) override {
88  return TimeZone::forError();
89  }
90 
92  switch (d.type) {
93  case TimeZone::kTypeError:
94  return TimeZone::forError();
95  case TimeZone::kTypeManual:
97  TimeOffset::forMinutes(d.stdOffsetMinutes),
98  TimeOffset::forMinutes(d.dstOffsetMinutes));
99  default:
100  return TimeZone::forError();
101  }
102  }
103 
104  uint16_t indexForZoneName(const char* /*name*/) const override {
105  return kInvalidIndex;
106  }
107 
108  uint16_t indexForZoneId(uint32_t /*id*/) const override {
109  return kInvalidIndex;
110  }
111 
112  uint16_t registrySize() const override { return 0; }
113 };
114 
137 template<typename ZI, typename ZR, typename ZSC>
138 class ZoneManagerImpl : public ZoneManager {
139  public:
140  TimeZone createForZoneName(const char* name) override {
141  const ZI* zoneInfo = mZoneRegistrar.getZoneInfoForName(name);
142  return createForZoneInfo(zoneInfo);
143  }
144 
145  TimeZone createForZoneId(uint32_t id) override {
146  const ZI* zoneInfo = mZoneRegistrar.getZoneInfoForId(id);
147  return createForZoneInfo(zoneInfo);
148  }
149 
150  TimeZone createForZoneIndex(uint16_t index) override {
151  const ZI* zoneInfo = mZoneRegistrar.getZoneInfoForIndex(index);
152  return createForZoneInfo(zoneInfo);
153  }
154 
155  TimeZone createForTimeZoneData(const TimeZoneData& d) override {
156  switch (d.type) {
157  case TimeZone::kTypeError:
158  return TimeZone::forError();
159  case TimeZone::kTypeManual:
161  TimeOffset::forMinutes(d.stdOffsetMinutes),
162  TimeOffset::forMinutes(d.dstOffsetMinutes));
163  case TimeZone::kTypeBasic:
164  case TimeZone::kTypeExtended:
165  return createForZoneId(d.zoneId);
166  default:
167  // Maybe this should return TimeZone::forError()?
168  return TimeZone();
169  }
170  }
171 
172  uint16_t indexForZoneName(const char* name) const override {
173  return mZoneRegistrar.findIndexForName(name);
174  }
175 
176  uint16_t indexForZoneId(uint32_t id) const override {
177  return mZoneRegistrar.findIndexForId(id);
178  }
179 
180  uint16_t registrySize() const override {
181  return mZoneRegistrar.registrySize();
182  }
183 
190  TimeZone createForZoneInfo(const ZI* zoneInfo) {
191  if (! zoneInfo) return TimeZone::forError();
192  return TimeZone(zoneInfo, &mZoneProcessorCache);
193  }
194 
195  protected:
202  ZoneManagerImpl(uint16_t registrySize, const ZI* const* zoneRegistry):
203  mZoneRegistrar(registrySize, zoneRegistry),
204  mZoneProcessorCache() {}
205 
206  private:
207  // disable copy constructor and assignment operator
208  ZoneManagerImpl(const ZoneManagerImpl&) = delete;
209  ZoneManagerImpl& operator=(const ZoneManagerImpl&) = delete;
210 
211  const ZR mZoneRegistrar;
212  ZSC mZoneProcessorCache;
213 };
214 
215 #if 1
216 
222 template<uint16_t SIZE>
223 class BasicZoneManager: public ZoneManagerImpl<basic::ZoneInfo,
224  BasicZoneRegistrar, BasicZoneProcessorCache<SIZE>> {
225  public:
226  BasicZoneManager(uint16_t registrySize,
227  const basic::ZoneInfo* const* zoneRegistry):
228  ZoneManagerImpl<basic::ZoneInfo, BasicZoneRegistrar,
229  BasicZoneProcessorCache<SIZE>>(registrySize, zoneRegistry) {}
230 };
231 
238 template<uint16_t SIZE>
239 class ExtendedZoneManager: public ZoneManagerImpl<extended::ZoneInfo,
240  ExtendedZoneRegistrar, ExtendedZoneProcessorCache<SIZE>> {
241  public:
242  ExtendedZoneManager(uint16_t registrySize,
243  const extended::ZoneInfo* const* zoneRegistry):
244  ZoneManagerImpl<extended::ZoneInfo, ExtendedZoneRegistrar,
245  ExtendedZoneProcessorCache<SIZE>>(registrySize, zoneRegistry) {}
246 };
247 
248 #else
249 
250 // NOTE: The following typedef seems shorter and easier to maintain. The
251 // problem is that it makes error messages basically impossible to decipher
252 // because the immensely long full template class name is printed out. There
253 // seems to be no difference in code size between the two. The compiler seems
254 // to optimize away the vtables of the parent and child classes.
255 
256 template<uint8_t SIZE>
257 using BasicZoneManager = ZoneManagerImpl<basic::ZoneInfo,
259 
260 template<uint8_t SIZE>
261 using ExtendedZoneManager = ZoneManagerImpl<extended::ZoneInfo,
263 
264 #endif
265 
266 }
267 
268 #endif
ace_time::ManualZoneManager::createForZoneId
TimeZone createForZoneId(uint32_t) override
Create a TimeZone for the given 32-bit zoneId.
Definition: ZoneManager.h:83
ace_time::BasicZoneProcessorCache
Definition: ZoneProcessorCache.h:102
ace_time::ZoneManagerImpl::ZoneManagerImpl
ZoneManagerImpl(uint16_t registrySize, const ZI *const *zoneRegistry)
Constructor.
Definition: ZoneManager.h:202
ace_time::ManualZoneManager
A ZoneManager that implements only createForTimeZoneData() to create TimeZones of type kTypeManual,...
Definition: ZoneManager.h:76
ace_time::ManualZoneManager::indexForZoneName
uint16_t indexForZoneName(const char *) const override
Find the registry index for the given time zone name.
Definition: ZoneManager.h:104
ace_time::ExtendedZoneProcessorCache
Definition: ZoneProcessorCache.h:108
ace_time::TimeZone::forError
static TimeZone forError()
Return a TimeZone representing an error condition.
Definition: TimeZone.h:141
ace_time::ZoneManagerImpl::createForZoneInfo
TimeZone createForZoneInfo(const ZI *zoneInfo)
Create a TimeZone from an explicit ZoneInfo reference.
Definition: ZoneManager.h:190
ace_time::ZoneManager::indexForZoneName
virtual uint16_t indexForZoneName(const char *name) const =0
Find the registry index for the given time zone name.
ace_time::ZoneRegistrar
Class that allows looking up the ZoneInfo (ZI) from its TZDB identifier (e.g.
Definition: ZoneRegistrar.h:51
ace_time::ZoneManager::createForZoneId
virtual TimeZone createForZoneId(uint32_t id)=0
Create a TimeZone for the given 32-bit zoneId.
ace_time::BasicZoneManager
An implementation of the ZoneManager which uses a registry of basic::ZoneInfo records.
Definition: ZoneManager.h:223
ace_time::ZoneManager::kInvalidIndex
static const uint16_t kInvalidIndex
Registry index which is not valid.
Definition: ZoneManager.h:27
ace_time::TimeOffset::forMinutes
static TimeOffset forMinutes(int16_t minutes)
Create TimeOffset from minutes from 00:00.
Definition: TimeOffset.h:83
ace_time::ZoneManager::indexForZoneId
virtual uint16_t indexForZoneId(uint32_t id) const =0
Find the registry index for the given time zone id.
ace_time::ZoneManager::createForZoneIndex
virtual TimeZone createForZoneIndex(uint16_t index)=0
Create a TimeZone for the given index in the ZoneInfo registry that was used to create this ZoneManag...
ace_time::ZoneManager::registrySize
virtual uint16_t registrySize() const =0
Return the number of elements in the registry.
ace_time::ManualZoneManager::registrySize
uint16_t registrySize() const override
Return the number of elements in the registry.
Definition: ZoneManager.h:112
ace_time::ZoneManager
Common interface to the BasicZoneManager and ExtendedZoneManager so that a single interface can be pa...
Definition: ZoneManager.h:24
ace_time::TimeZoneData
Data structure that captures the internal state of a TimeZone object with enough information so that ...
Definition: TimeZoneData.h:38
ace_time::ManualZoneManager::createForZoneIndex
TimeZone createForZoneIndex(uint16_t) override
Create a TimeZone for the given index in the ZoneInfo registry that was used to create this ZoneManag...
Definition: ZoneManager.h:87
ace_time::ManualZoneManager::createForTimeZoneData
TimeZone createForTimeZoneData(const TimeZoneData &d) override
Create a TimeZone from the TimeZoneData created by TimeZone::toTimeZoneData().
Definition: ZoneManager.h:91
ace_time::ExtendedZoneManager
An implementation of the ZoneManager which uses a registry of extended::ZoneInfo records.
Definition: ZoneManager.h:239
ace_time::ZoneManagerImpl
A templatized implementation of ZoneManager that binds the (Basic|Extended)ZoneRegistrar with the cor...
Definition: TimeZone.h:23
ace_time::TimeZone
Class that describes a time zone.
Definition: TimeZone.h:84
ace_time::TimeZone::forTimeOffset
static TimeZone forTimeOffset(TimeOffset stdOffset, TimeOffset dstOffset=TimeOffset())
Factory method to create from a UTC offset and an optional DST offset.
Definition: TimeZone.h:106
ace_time::ZoneManager::createForTimeZoneData
virtual TimeZone createForTimeZoneData(const TimeZoneData &d)=0
Create a TimeZone from the TimeZoneData created by TimeZone::toTimeZoneData().
ace_time::ManualZoneManager::indexForZoneId
uint16_t indexForZoneId(uint32_t) const override
Find the registry index for the given time zone id.
Definition: ZoneManager.h:108
ace_time::ZoneManager::createForZoneName
virtual TimeZone createForZoneName(const char *name)=0
Create a TimeZone for the given zone name (e.g.
ace_time::ManualZoneManager::createForZoneName
TimeZone createForZoneName(const char *) override
Create a TimeZone for the given zone name (e.g.
Definition: ZoneManager.h:79