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

Class that describes a time zone. More...

#include <TimeZone.h>

Collaboration diagram for ace_time::TimeZone:
Collaboration graph
[legend]

Public Member Functions

 TimeZone ()
 Default constructor. More...
 
uint8_t getType () const
 Return the type of TimeZone. More...
 
TimeOffset getUtcOffset (acetime_t epochSeconds) const
 Return the total UTC offset at epochSeconds, including DST offset. More...
 
TimeOffset getDeltaOffset (acetime_t epochSeconds) const
 Return the DST offset from standard UTC offset at epochSeconds. More...
 
OffsetDateTime getOffsetDateTime (const LocalDateTime &ldt) const
 Return the best estimate of the OffsetDateTime at the given LocalDateTime for the current TimeZone. More...
 
void printTo (Print &printer) const
 Print the human readable representation of the time zone. More...
 
void printAbbrevTo (Print &printer, acetime_t epochSeconds) const
 Print the time zone abbreviation for the given epochSeconds. More...
 
bool isDst () const
 Return the isDst() value of the underlying ManualZoneSpecifier. More...
 
void isDst (bool dst)
 Sets the isDst() flag of the underlying ManualZoneSpecifier. More...
 
 TimeZone (const TimeZone &)=default
 
TimeZoneoperator= (const TimeZone &)=default
 

Static Public Member Functions

static TimeZone forTimeOffset (TimeOffset offset)
 Factory method to create from a fixed UTC offset. More...
 
static TimeZone forZoneSpecifier (const ZoneSpecifier *zoneSpecifier)
 Factory method to create from a ZoneSpecifier. More...
 

Static Public Attributes

static const uint8_t kTypeFixed = 0
 
static const uint8_t kTypeManual = ZoneSpecifier::kTypeManual
 
static const uint8_t kTypeBasic = ZoneSpecifier::kTypeBasic
 
static const uint8_t kTypeExtended = ZoneSpecifier::kTypeExtended
 

Friends

bool operator== (const TimeZone &a, const TimeZone &b)
 

Detailed Description

Class that describes a time zone.

There are 2 colloquial usages of "time zone". The first refers to a simple fixed offset from UTC. For example, we may say that "we are in -05:00 time zone". The second is a geographical region that obeys a consistent set of rules regarding the value of the UTC offset, and when the transitions to DST happens (if at all). The best known source of these geographical regions is the TZ Database maintained by IANA (https://www.iana.org/time-zones). The TimeZone class supports both meanings.

There are 4 types of TimeZone:

The TimeZone class really really wants to be a reference type. In other words, it would be very convenient if the client code could create this object on the heap, and pass it around using a pointer (or smart pointer) to the ZonedDateTime class and shared among multiple ZonedDateTime objects. This would also allow new TimeZones to be created, while allowing older instances of ZonedDateTime to hold on to the previous versions of TimeZone.

However, in a small memory embedded environment (like Arduino Nano or Micro with only 2kB of RAM), I want to avoid any use of the heap (new operator or malloc()) inside the AceTime library. I separated out the memory intensive or mutable features of the TimeZone class into the separate ZoneSpecifier class. The ZoneSpecifier object should be created once at initialization time of the application (either statically allocated or potentially on the heap early in the application start up).

The TimeZone class becomes a thin wrapper around a ZoneSpecifier object (essentially acting like a smart pointer in some sense). It should be treated as a value type and passed around by value or by const reference.

An alternative implementation would use an inheritance hierarchy for the TimeZone, with 2 subclasses (ManualTimeZone and AutoTimeZone). However this means that the TimeZone object can no longer be passed around by value, and the ZonedDateTime is forced to hold on to the TimeZone object using a pointer. It then becomes very difficult to change the offset and DST fields of the ManualTimeZone. Using a single TimeZone class and implementing it as a value type simplifies a lot of code.

Serialization and Deserialization:

Serializing and deserializing the TimeZone object is difficult because we need to save information from both the TimeZone object and (potentially) the ZoneSpecifier object. The TimeZone object can be identified by its getType() parameter. If this type is kTypeFixed, then the UTC offset is sufficient to reconstruct the TimeZone. If this type is kTypeManual, the underlying ManualZoneSpecifier can be fully described using 2 parameters (the timeOffset and the isDst flag.

If the type is kTypeBasic or kTypeExtended, the underlying BasicZoneSpecifier and ExtendedZoneSpecifier can both be uniquely identified by the fully-qualified zone identifier (e.g. "America/Los_Angeles"). However, due to memory limitations, most Arduino environments cannot contain the entire TZ Database with all 348 zones supported by AceTime. Therefore, there is currently no ability to create a BasicZoneSpecifier or ExtendedZoneSpecifier from its fully-qualified zone name.

Since most Arduino environments will support only a handful of hardcoded time zones, the recommended procedure is to associate each of these zones with a small numerical identifier, and use that to recreate the appropriate instance of BasicZoneSpecifier or ExtendedZoneSpecifier.

On larger Arduino environments (e.g. ESP8266 or ESP32) with enough memory, it may be possible to allow the creation of a BasicZoneSpecifier or ExtendedZoneSpecifier from the fully-qualified zone name. It would then be sufficient to just store the fully-qualified zone name, instead of creating a customized mapping table. However, we still would need to worry about TZ Database version skew. In other words, the code needs to handle siutations where the serialized zone name using one version of the TZ Database is not recognized by a new version of TZ Database.

Definition at line 96 of file TimeZone.h.

Constructor & Destructor Documentation

◆ TimeZone()

ace_time::TimeZone::TimeZone ( )
inline

Default constructor.

Definition at line 123 of file TimeZone.h.

Member Function Documentation

◆ forTimeOffset()

static TimeZone ace_time::TimeZone::forTimeOffset ( TimeOffset  offset)
inlinestatic

Factory method to create from a fixed UTC offset.

Parameters
offsetthe fixed UTC offset, use TimeOffset() for UTC

Definition at line 108 of file TimeZone.h.

◆ forZoneSpecifier()

static TimeZone ace_time::TimeZone::forZoneSpecifier ( const ZoneSpecifier zoneSpecifier)
inlinestatic

Factory method to create from a ZoneSpecifier.

Parameters
zoneSpecifieran instance of ManualZoneSpecifier, BasicZoneSpecifier, or ExtendedZoneSpecifier. Cannot be nullptr.

Definition at line 118 of file TimeZone.h.

◆ getDeltaOffset()

TimeOffset ace_time::TimeZone::getDeltaOffset ( acetime_t  epochSeconds) const
inline

Return the DST offset from standard UTC offset at epochSeconds.

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

Definition at line 145 of file TimeZone.h.

◆ getOffsetDateTime()

OffsetDateTime ace_time::TimeZone::getOffsetDateTime ( const LocalDateTime ldt) const
inline

Return the best estimate of the OffsetDateTime at the given LocalDateTime for the current TimeZone.

Used by ZonedDateTime::forComponents(), so intended to be used mostly for testing and debugging.

Definition at line 157 of file TimeZone.h.

◆ getType()

uint8_t ace_time::TimeZone::getType ( ) const
inline

Return the type of TimeZone.

This value is useful for serializing and deserializing (or storing and restoring) the TimeZone object.

Definition at line 131 of file TimeZone.h.

◆ getUtcOffset()

TimeOffset ace_time::TimeZone::getUtcOffset ( acetime_t  epochSeconds) const
inline

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

Definition at line 134 of file TimeZone.h.

◆ isDst() [1/2]

bool ace_time::TimeZone::isDst ( ) const
inline

Return the isDst() value of the underlying ManualZoneSpecifier.

This is a convenience method that is valid only if the TimeZone was constructed using a ManualZoneSpecifier. Returns false for all other type of TimeZone. This is intended to be used by applications which allows the user to set the UTC offset and DST flag manually (e.g. examples/WorldClock.ino).

Definition at line 191 of file TimeZone.h.

◆ isDst() [2/2]

void ace_time::TimeZone::isDst ( bool  dst)
inline

Sets the isDst() flag of the underlying ManualZoneSpecifier.

Does nothing for any other type of TimeZone. This is a convenience method for applications that allow the user to set the DST flag manually (e.g. examples/WorldClock).

Definition at line 202 of file TimeZone.h.

◆ printAbbrevTo()

void ace_time::TimeZone::printAbbrevTo ( Print &  printer,
acetime_t  epochSeconds 
) const

Print the time zone abbreviation for the given epochSeconds.

  • kTypeFixed at UTC is printed as "UTC" or "+/-hh:mm"
  • kTypeManual is printed as "{abbrev}" (e.g. "PDT")
  • kTypeBasic is printed as "{abbrev}" (e.g. "PDT")
  • kTypeExtended is printed as "{abbrev}" (e.g. "PDT")

Definition at line 19 of file TimeZone.cpp.

◆ printTo()

void ace_time::TimeZone::printTo ( Print &  printer) const

Print the human readable representation of the time zone.

  • kTypeFixed at UTC is printed as "UTC" or "+/-hh:mm"
  • kTypeManual is printed as "+/-hh:mm(STD|DST)" (e.g. "-08:00(DST)")
  • kTypeBasic is printed as "{zonename}" (e.g. "America/Los_Angeles")
  • kTypeExtended is printed as "{zonename}" (e.g. "America/Los_Angeles")

Definition at line 7 of file TimeZone.cpp.

Member Data Documentation

◆ mOffset

TimeOffset ace_time::TimeZone::mOffset

Used if mType == mTypeFixed.

Definition at line 242 of file TimeZone.h.

◆ mZoneSpecifier

const ZoneSpecifier* ace_time::TimeZone::mZoneSpecifier

Used if mType == mTypeZoneSpecifier.

Definition at line 245 of file TimeZone.h.


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