AceTime  0.6
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.
OffsetDateTime.h
1 /*
2  * MIT License
3  * Copyright (c) 2018 Brian T. Park
4  */
5 
6 #ifndef ACE_TIME_OFFSET_DATE_TIME_H
7 #define ACE_TIME_OFFSET_DATE_TIME_H
8 
9 #include <stdint.h>
10 #include "TimeOffset.h"
11 #include "LocalDateTime.h"
12 
13 class Print;
14 
15 namespace ace_time {
16 
34  public:
35 
39  return OffsetDateTime(localDateTime, timeOffset);
40  }
41 
53  static OffsetDateTime forComponents(int16_t year, uint8_t month, uint8_t
54  day, uint8_t hour, uint8_t minute, uint8_t second, TimeOffset
55  timeOffset) {
56  auto ldt = LocalDateTime::forComponents(year, month, day, hour, minute,
57  second);
58  return OffsetDateTime(ldt, timeOffset);
59  }
60 
71  static OffsetDateTime forEpochSeconds(acetime_t epochSeconds,
73  if (epochSeconds != LocalDate::kInvalidEpochSeconds) {
74  epochSeconds += timeOffset.toSeconds();
75  }
76  auto ldt = LocalDateTime::forEpochSeconds(epochSeconds);
77  return OffsetDateTime(ldt, timeOffset);
78  }
79 
85  static OffsetDateTime forUnixSeconds(acetime_t unixSeconds,
87  acetime_t epochSeconds = (unixSeconds == LocalDate::kInvalidEpochSeconds)
88  ? unixSeconds
89  : unixSeconds - LocalDate::kSecondsSinceUnixEpoch;
90  return forEpochSeconds(epochSeconds, timeOffset);
91  }
92 
112  static OffsetDateTime forDateString(const char* dateString);
113 
121  static OffsetDateTime forDateStringChainable(const char*& dateString);
122 
128  static OffsetDateTime forDateString(const __FlashStringHelper* dateString) {
129  // Copy the F() string into a buffer. Use strncpy_P() because ESP32 and
130  // ESP8266 do not have strlcpy_P(). We need +1 for the '\0' character and
131  // another +1 to determine if the dateString is too long to fit.
132  char buffer[kDateStringLength + 2];
133  strncpy_P(buffer, (const char*) dateString, sizeof(buffer));
134  buffer[kDateStringLength + 1] = 0;
135 
136  // check if the original F() was too long
137  size_t len = strlen(buffer);
138  if (len > kDateStringLength) {
139  return forError();
140  }
141 
142  return forDateString(buffer);
143  }
144 
148  }
149 
151  explicit OffsetDateTime() {}
152 
154  bool isError() const {
155  // Check mTimeOffset first because it's expected to be invalid more often.
156  return mTimeOffset.isError() || mLocalDateTime.isError();
157  }
158 
160  int16_t year() const { return mLocalDateTime.year(); }
161 
163  void year(int16_t year) { mLocalDateTime.year(year); }
164 
166  int8_t yearTiny() const { return mLocalDateTime.yearTiny(); }
167 
169  void yearTiny(int8_t yearTiny) { mLocalDateTime.yearTiny(yearTiny); }
170 
172  uint8_t month() const { return mLocalDateTime.month(); }
173 
175  void month(uint8_t month) { mLocalDateTime.month(month); }
176 
178  uint8_t day() const { return mLocalDateTime.day(); }
179 
181  void day(uint8_t day) { mLocalDateTime.day(day); }
182 
184  uint8_t hour() const { return mLocalDateTime.hour(); }
185 
187  void hour(uint8_t hour) { mLocalDateTime.hour(hour); }
188 
190  uint8_t minute() const { return mLocalDateTime.minute(); }
191 
193  void minute(uint8_t minute) { mLocalDateTime.minute(minute); }
194 
196  uint8_t second() const { return mLocalDateTime.second(); }
197 
199  void second(uint8_t second) { mLocalDateTime.second(second); }
200 
202  uint8_t dayOfWeek() const { return mLocalDateTime.dayOfWeek(); }
203 
205  TimeOffset timeOffset() const { return mTimeOffset; }
206 
208  void timeOffset(TimeOffset timeOffset) { mTimeOffset = timeOffset; }
209 
211  const LocalDateTime& localDateTime() const { return mLocalDateTime; }
212 
214  const LocalDate& localDate() const { return mLocalDateTime.localDate(); }
215 
217  const LocalTime& localTime() const { return mLocalDateTime.localTime(); }
218 
224  acetime_t epochSeconds = toEpochSeconds();
225  return OffsetDateTime::forEpochSeconds(epochSeconds, timeOffset);
226  }
227 
232  acetime_t toEpochDays() const {
234 
235  acetime_t epochDays = mLocalDateTime.localDate().toEpochDays();
236 
237  // Increment or decrement the day count depending on the time offset.
238  acetime_t timeOffset = mLocalDateTime.localTime().toSeconds()
239  - mTimeOffset.toSeconds();
240  if (timeOffset >= 86400) return epochDays + 1;
241  if (timeOffset < 0) return epochDays - 1;
242  return epochDays;
243  }
244 
246  acetime_t toUnixDays() const {
249  }
250 
255  acetime_t toEpochSeconds() const {
257  return mLocalDateTime.toEpochSeconds() - mTimeOffset.toSeconds();
258  }
259 
267  acetime_t toUnixSeconds() const {
270  }
271 
278  int8_t compareTo(const OffsetDateTime& that) const {
279  acetime_t thisSeconds = toEpochSeconds();
280  acetime_t thatSeconds = that.toEpochSeconds();
281  if (thisSeconds < thatSeconds) return -1;
282  if (thisSeconds > thatSeconds) return 1;
283  return 0;
284  }
285 
291  void printTo(Print& printer) const;
292 
293  // Use default copy constructor and assignment operator.
294  OffsetDateTime(const OffsetDateTime&) = default;
295  OffsetDateTime& operator=(const OffsetDateTime&) = default;
296 
297  private:
298  friend bool operator==(const OffsetDateTime& a, const OffsetDateTime& b);
299 
301  static const uint8_t kDateStringLength = 25;
302 
304  explicit OffsetDateTime(const LocalDateTime& ldt, TimeOffset timeOffset):
305  mLocalDateTime(ldt),
306  mTimeOffset(timeOffset) {}
307 
308  LocalDateTime mLocalDateTime;
309  TimeOffset mTimeOffset;
310 };
311 
317 inline bool operator==(const OffsetDateTime& a, const OffsetDateTime& b) {
318  return a.mLocalDateTime == b.mLocalDateTime
319  && a.mTimeOffset == b.mTimeOffset;
320 }
321 
323 inline bool operator!=(const OffsetDateTime& a, const OffsetDateTime& b) {
324  return ! (a == b);
325 }
326 
327 }
328 
329 #endif
acetime_t toSeconds() const
Return the number of seconds since midnight.
Definition: LocalTime.h:137
const LocalTime & localTime() const
Return the LocalTime.
static const acetime_t kSecondsSinceUnixEpoch
Number of seconds from Unix epoch (1970-01-01 00:00:00Z) to the AceTime epoch (2000-01-01 00:00:00Z)...
Definition: LocalDate.h:57
static TimeOffset forError()
Return an error indicator.
Definition: TimeOffset.h:110
uint8_t minute() const
Return the minute.
int16_t year() const
Return the year.
uint8_t minute() const
Return the minute.
static const acetime_t kDaysSinceUnixEpoch
Number of days from Unix epoch (1970-01-01 00:00:00Z) to the AceTime epoch (2000-01-01 00:00:00Z)...
Definition: LocalDate.h:63
uint8_t second() const
Return the second.
void minute(uint8_t minute)
Set the minute.
static const acetime_t kInvalidEpochDays
Sentinel epochDays which indicates an error.
Definition: LocalDate.h:48
int8_t yearTiny() const
Return the single-byte year offset from year 2000.
void day(uint8_t day)
Set the day of the month.
acetime_t toEpochDays() const
Return number of whole days since AceTime epoch (2000-01-01 00:00:00Z), taking into account the offse...
static const acetime_t kInvalidEpochSeconds
Sentinel epochSeconds which indicates an error.
Definition: LocalDate.h:51
The time (hour, minute, second) fields representing the time without regards to the day or the time z...
Definition: LocalTime.h:26
uint8_t dayOfWeek() const
Return the day of the week, Monday=1, Sunday=7 (per ISO 8601).
bool isError() const
Return true if this TimeOffset represents an error.
Definition: TimeOffset.h:155
OffsetDateTime convertToTimeOffset(TimeOffset timeOffset) const
Create a OffsetDateTime in a different offset zone code (with the same epochSeconds).
acetime_t toEpochDays() const
Return number of days since AceTime epoch (2000-01-01 00:00:00Z).
Definition: LocalDate.h:280
uint8_t month() const
Return the month with January=1, December=12.
static OffsetDateTime forLocalDateTimeAndOffset(const LocalDateTime &localDateTime, TimeOffset timeOffset)
Factory method from LocalDateTime and TimeOffset.
int32_t toSeconds() const
Return the time offset as seconds.
Definition: TimeOffset.h:133
uint8_t hour() const
Return the hour.
uint8_t day() const
Return the day of the month.
int8_t yearTiny() const
Return the single-byte year offset from year 2000.
static LocalDateTime forEpochSeconds(acetime_t epochSeconds)
Factory method.
Definition: LocalDateTime.h:67
acetime_t toUnixSeconds() const
Return the number of seconds from Unix epoch 1970-01-01 00:00:00Z.
void year(int16_t year)
Set the year.
void printTo(Print &printer) const
Print OffsetDateTime to &#39;printer&#39; in ISO 8601 format.
static OffsetDateTime forComponents(int16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, TimeOffset timeOffset)
Factory method using separated date, time, and UTC offset fields.
int8_t compareTo(const OffsetDateTime &that) const
Compare this OffsetDateTime with another OffsetDateTime, and return (<0, 0, >0) according to whether ...
OffsetDateTime()
Constructor.
void second(uint8_t second)
Set the second.
uint8_t month() const
Return the month with January=1, December=12.
static OffsetDateTime forEpochSeconds(acetime_t epochSeconds, TimeOffset timeOffset)
Factory method.
static LocalDateTime forComponents(int16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)
Factory method using separated date and time components.
Definition: LocalDateTime.h:40
acetime_t toEpochSeconds() const
Return seconds since AceTime epoch 2000-01-01 00:00:00Z, after assuming that the date and time compon...
void timeOffset(TimeOffset timeOffset)
Set the offset zone.
void yearTiny(int8_t yearTiny)
Set the single-byte year offset from year 2000.
const LocalDate & localDate() const
Return the LocalDate.
friend bool operator==(const OffsetDateTime &a, const OffsetDateTime &b)
Return true if two OffsetDateTime objects are equal in all components.
TimeOffset timeOffset() const
Return the offset zone of the OffsetDateTime.
const LocalTime & localTime() const
Return the LocalTime.
void month(uint8_t month)
Set the month.
static OffsetDateTime forDateString(const __FlashStringHelper *dateString)
Factory method.
acetime_t toUnixDays() const
Return the number of days since Unix epoch (1970-01-01 00:00:00).
uint8_t hour() const
Return the hour.
int16_t year() const
Return the year.
const LocalDateTime & localDateTime() const
Return the LocalDateTime.
uint8_t dayOfWeek() const
Return the day of the week, Monday=1, Sunday=7 (per ISO 8601).
The date (year, month, day), time (hour, minute, second) and offset from UTC (timeOffset).
uint8_t second() const
Return the second.
acetime_t toEpochSeconds() const
Return seconds since AceTime epoch (2000-01-01 00:00:00Z), taking into account the offset zone...
A thin wrapper that represents a time offset from a reference point, usually 00:00 at UTC...
Definition: TimeOffset.h:58
static LocalDateTime forError()
Factory method that returns an instance where isError() returns true.
The date (year, month, day) representing the date without regards to time zone.
Definition: LocalDate.h:36
void hour(uint8_t hour)
Set the hour.
const LocalDate & localDate() const
Return the LocalDate.
static OffsetDateTime forDateStringChainable(const char *&dateString)
Variant of forDateString() that updates the pointer to the next unprocessed character.
uint8_t day() const
Return the day of the month.
static OffsetDateTime forUnixSeconds(acetime_t unixSeconds, TimeOffset timeOffset)
Factory method that takes the number of seconds since Unix Epoch of 1970-01-01.
bool isError() const
Return true if any component indicates an error condition.
bool isError() const
Return true if any component indicates an error condition.
static OffsetDateTime forError()
Factory method that returns an instance whose isError() is true.
Class that holds the date-time as the components (year, month, day, hour, minute, second) without reg...
Definition: LocalDateTime.h:27
static OffsetDateTime forDateString(const char *dateString)
Factory method.