AceTime  0.7
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.
Public Member Functions | Static Public Member Functions | Friends | List of all members
ace_time::BasicZoneProcessor Class Reference

An implementation of ZoneProcessor that supports a subset of the zones containing in the TZ Database. More...

#include <BasicZoneProcessor.h>

Inheritance diagram for ace_time::BasicZoneProcessor:
Inheritance graph
[legend]
Collaboration diagram for ace_time::BasicZoneProcessor:
Collaboration graph
[legend]

Public Member Functions

 BasicZoneProcessor (const basic::ZoneInfo *zoneInfo=nullptr)
 Constructor. More...
 
const void * getZoneInfo () const override
 Return the underlying ZoneInfo. More...
 
uint32_t getZoneId () const override
 Return the unique stable zoneId. More...
 
TimeOffset getUtcOffset (acetime_t epochSeconds) const override
 Return the total UTC offset at epochSeconds, including DST offset. More...
 
TimeOffset getDeltaOffset (acetime_t epochSeconds) const override
 Return the DST delta offset at epochSeconds. More...
 
const char * getAbbrev (acetime_t epochSeconds) const override
 Return the time zone abbreviation at epochSeconds. More...
 
OffsetDateTime getOffsetDateTime (const LocalDateTime &ldt) const override
 
void printTo (Print &printer) const override
 Print a human-readable identifier (e.g. More...
 
void printShortTo (Print &printer) const override
 Print a short human-readable identifier (e.g. More...
 
void log () const
 Used only for debugging. More...
 
- Public Member Functions inherited from ace_time::ZoneProcessor
uint8_t getType () const
 Return the kTypeXxx of the current instance. More...
 

Static Public Member Functions

static basic::MonthDay calcStartDayOfMonth (int16_t year, uint8_t month, uint8_t onDayOfWeek, int8_t onDayOfMonth)
 Calculate the actual (month, day) of the expresssion (onDayOfWeek >= onDayOfMonth) or (onDayOfWeek <= onDayOfMonth). More...
 

Friends

class ::BasicZoneProcessorTest_init_primitives
 
class ::BasicZoneProcessorTest_init
 
class ::BasicZoneProcessorTest_setZoneInfo
 
class ::BasicZoneProcessorTest_createAbbreviation
 
class ::BasicZoneProcessorTest_calcStartDayOfMonth
 
class ::BasicZoneProcessorTest_calcRuleOffsetCode
 
template<uint8_t SIZE, uint8_t TYPE, typename ZS , typename ZI , typename ZIB >
class ZoneProcessorCacheImpl
 

Additional Inherited Members

- Static Public Attributes inherited from ace_time::ZoneProcessor
static const uint8_t kTypeBasic = 2
 Indicate BasicZoneProcessor. More...
 
static const uint8_t kTypeExtended = 3
 Indicate ExtendedZoneProcessor. More...
 
- Protected Member Functions inherited from ace_time::ZoneProcessor
 ZoneProcessor (const ZoneProcessor &)=delete
 
ZoneProcessoroperator= (const ZoneProcessor &)=delete
 
 ZoneProcessor (uint8_t type)
 Constructor. More...
 
- Protected Attributes inherited from ace_time::ZoneProcessor
uint8_t mType
 

Detailed Description

An implementation of ZoneProcessor that supports a subset of the zones containing in the TZ Database.

The supported list of zones, as well as the list of unsupported zones, are is listed in the zonedb/zone_info.h header file. The constructor expects a pointer to one of the ZoneInfo structures declared in the zone_infos.h file.

The internal ZoneRule and ZoneEra records that match the year of the given epochSeconds are cached for performance. The expectation is that repeated calls to the various methods will have epochSeconds which do not vary too greatly and will occur in the same year.

The Rule records are transition points which look like this:

* Rule  NAME  FROM    TO  TYPE    IN     ON        AT      SAVE    LETTER/S
* 

Each record is represented by basic::ZoneRule and the entire collection is represented by basic::ZonePolicy.

The Zone records define the region which follows a specific set of Rules for certain time periods (given by UNTIL below):

* Zone NAME              GMTOFF    RULES FORMAT  [UNTIL]
* 

Each record is represented by basic::ZoneEra and the entire collection is represented by basic::ZoneInfo.

This class assumes that the various components of ZoneInfo, ZoneEra, and ZonePolicy, ZoneRule have a number of limitations and constraints which simplify the implementation of this class. The tzcompiler.py script will remove zones which do not meet these constraints when generating the structs defined by zonedb/zone_infos.h. The constraints are at least the following (see tools/transformer.py for the authoratative algorithm):

Even with these limitations, zonedb/zone_info.h shows that 231 out of a total of 359 zones are supported by BasicZoneProcessor.

Not thread-safe.

Definition at line 184 of file BasicZoneProcessor.h.

Constructor & Destructor Documentation

◆ BasicZoneProcessor()

ace_time::BasicZoneProcessor::BasicZoneProcessor ( const basic::ZoneInfo zoneInfo = nullptr)
inlineexplicit

Constructor.

The ZoneInfo is given only for unit tests.

Parameters
zoneInfopointer to a ZoneInfo.

Definition at line 190 of file BasicZoneProcessor.h.

Member Function Documentation

◆ calcStartDayOfMonth()

static basic::MonthDay ace_time::BasicZoneProcessor::calcStartDayOfMonth ( int16_t  year,
uint8_t  month,
uint8_t  onDayOfWeek,
int8_t  onDayOfMonth 
)
inlinestatic

Calculate the actual (month, day) of the expresssion (onDayOfWeek >= onDayOfMonth) or (onDayOfWeek <= onDayOfMonth).

There are 4 combinations:

* onDayOfWeek=0, onDayOfMonth=(1-31): exact match
* onDayOfWeek=1-7, onDayOfMonth=1-31: dayOfWeek>=dayOfMonth
* onDayOfWeek=1-7, onDayOfMonth=0: last{dayOfWeek}
* onDayOfWeek=1-7, onDayOfMonth=-(1-31): dayOfWeek<=dayOfMonth
* 

Caveats: This method handles expressions which crosses month boundaries, but not year boundaries (e.g. Jan to Dec of the previous year, or Dec to Jan of the following year.)

Not private, used by ExtendedZoneProcessor.

Definition at line 334 of file BasicZoneProcessor.h.

◆ getAbbrev()

const char* ace_time::BasicZoneProcessor::getAbbrev ( acetime_t  epochSeconds) const
inlineoverridevirtual

Return the time zone abbreviation at epochSeconds.

Returns an empty string ("") if an error occurs. The returned pointer points to a char buffer that could get overriden by subsequent method calls to this object. The pointer must not be stored permanently, it should be used as soon as possible (e.g. printed out).

This is an experimental method that has not been tested thoroughly. Use with caution.

Implements ace_time::ZoneProcessor.

Definition at line 215 of file BasicZoneProcessor.h.

◆ getDeltaOffset()

TimeOffset ace_time::BasicZoneProcessor::getDeltaOffset ( acetime_t  epochSeconds) const
inlineoverridevirtual

Return the DST delta offset at epochSeconds.

This is an experimental method that has not been tested thoroughly. Use with caution. Returns TimeOffset::forError() if an error occurs.

Implements ace_time::ZoneProcessor.

Definition at line 208 of file BasicZoneProcessor.h.

◆ getOffsetDateTime()

OffsetDateTime ace_time::BasicZoneProcessor::getOffsetDateTime ( const LocalDateTime ldt) const
inlineoverridevirtual

The Transitions calculated by BasicZoneProcessor contain only the epochSeconds when each transition occurs. They do not contain the local date/time components of the transition. This design reduces the amount of memory required by BasicZoneProcessor, but this means that the information needed to implement this method correctly does not exist.

The implementation is somewhat of a hack:

0) Use the localDateTime to extract the offset, assuming that the localDatetime is UTC. This will get us within 12-14h of the correct UTC offset. 1) Use (localDateTime, offset0) to determine offset1. 2) Use (localdateTime, offset1) to determine offset2. 3) Finally, check if offset1 and offset2 are equal. If they are we reached equilibrium so we can just return (localDateTime, offset1). If they are not equal, then we have a cycle because the localDateTime occurred in a DST gap (STD->DST transition) or overlap (DST->STD transition). We arbitrarily pick the offset of the later epochSeconds since that seems to match closely to what most people would expect to happen in a gap or overlap (e.g. In the gap of 2am->3am, a 2:30am would get shifted to 3:30am.)

The code is written slightly ackwardly to try to encourage the compiler to perform Return Value Optimization. For example, I use only a single OffsetDateTime instance, and I don't use early return.

Implements ace_time::ZoneProcessor.

Definition at line 249 of file BasicZoneProcessor.h.

◆ getUtcOffset()

TimeOffset ace_time::BasicZoneProcessor::getUtcOffset ( acetime_t  epochSeconds) const
inlineoverridevirtual

Return the total UTC offset at epochSeconds, including DST offset.

Returns TimeOffset::forError() if an error occurs.

Implements ace_time::ZoneProcessor.

Definition at line 201 of file BasicZoneProcessor.h.

◆ getZoneId()

uint32_t ace_time::BasicZoneProcessor::getZoneId ( ) const
inlineoverridevirtual

Return the unique stable zoneId.

Implements ace_time::ZoneProcessor.

Definition at line 199 of file BasicZoneProcessor.h.

◆ getZoneInfo()

const void* ace_time::BasicZoneProcessor::getZoneInfo ( ) const
inlineoverridevirtual

Return the underlying ZoneInfo.

Implements ace_time::ZoneProcessor.

Definition at line 195 of file BasicZoneProcessor.h.

◆ log()

void ace_time::BasicZoneProcessor::log ( ) const
inline

Used only for debugging.

Definition at line 298 of file BasicZoneProcessor.h.

◆ printShortTo()

void ace_time::BasicZoneProcessor::printShortTo ( Print &  printer) const
overridevirtual

Print a short human-readable identifier (e.g.

"Los_Angeles")

Implements ace_time::ZoneProcessor.

Definition at line 16 of file BasicZoneProcessor.cpp.

◆ printTo()

void ace_time::BasicZoneProcessor::printTo ( Print &  printer) const
overridevirtual

Print a human-readable identifier (e.g.

"America/Los_Angeles").

Implements ace_time::ZoneProcessor.

Definition at line 12 of file BasicZoneProcessor.cpp.


The documentation for this class was generated from the following files: