AceTime  1.1
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 
170  int8_t yearTiny() const { return mLocalDateTime.yearTiny(); }
171 
177  void yearTiny(int8_t yearTiny) { mLocalDateTime.yearTiny(yearTiny); }
178 
180  uint8_t month() const { return mLocalDateTime.month(); }
181 
183  void month(uint8_t month) { mLocalDateTime.month(month); }
184 
186  uint8_t day() const { return mLocalDateTime.day(); }
187 
189  void day(uint8_t day) { mLocalDateTime.day(day); }
190 
192  uint8_t hour() const { return mLocalDateTime.hour(); }
193 
195  void hour(uint8_t hour) { mLocalDateTime.hour(hour); }
196 
198  uint8_t minute() const { return mLocalDateTime.minute(); }
199 
201  void minute(uint8_t minute) { mLocalDateTime.minute(minute); }
202 
204  uint8_t second() const { return mLocalDateTime.second(); }
205 
207  void second(uint8_t second) { mLocalDateTime.second(second); }
208 
210  uint8_t dayOfWeek() const { return mLocalDateTime.dayOfWeek(); }
211 
213  TimeOffset timeOffset() const { return mTimeOffset; }
214 
216  void timeOffset(TimeOffset timeOffset) { mTimeOffset = timeOffset; }
217 
219  const LocalDateTime& localDateTime() const { return mLocalDateTime; }
220 
222  const LocalDate& localDate() const { return mLocalDateTime.localDate(); }
223 
225  const LocalTime& localTime() const { return mLocalDateTime.localTime(); }
226 
232  acetime_t epochSeconds = toEpochSeconds();
233  return OffsetDateTime::forEpochSeconds(epochSeconds, timeOffset);
234  }
235 
240  acetime_t toEpochDays() const {
242 
243  acetime_t epochDays = mLocalDateTime.localDate().toEpochDays();
244 
245  // Increment or decrement the day count depending on the time offset.
246  acetime_t timeOffset = mLocalDateTime.localTime().toSeconds()
247  - mTimeOffset.toSeconds();
248  if (timeOffset >= 86400) return epochDays + 1;
249  if (timeOffset < 0) return epochDays - 1;
250  return epochDays;
251  }
252 
254  acetime_t toUnixDays() const {
257  }
258 
263  acetime_t toEpochSeconds() const {
265  return mLocalDateTime.toEpochSeconds() - mTimeOffset.toSeconds();
266  }
267 
275  acetime_t toUnixSeconds() const {
278  }
279 
286  int8_t compareTo(const OffsetDateTime& that) const {
287  acetime_t thisSeconds = toEpochSeconds();
288  acetime_t thatSeconds = that.toEpochSeconds();
289  if (thisSeconds < thatSeconds) return -1;
290  if (thisSeconds > thatSeconds) return 1;
291  return 0;
292  }
293 
299  void printTo(Print& printer) const;
300 
301  // Use default copy constructor and assignment operator.
302  OffsetDateTime(const OffsetDateTime&) = default;
303  OffsetDateTime& operator=(const OffsetDateTime&) = default;
304 
305  private:
306  friend bool operator==(const OffsetDateTime& a, const OffsetDateTime& b);
307 
309  static const uint8_t kDateStringLength = 25;
310 
312  explicit OffsetDateTime(const LocalDateTime& ldt, TimeOffset timeOffset):
313  mLocalDateTime(ldt),
314  mTimeOffset(timeOffset) {}
315 
316  LocalDateTime mLocalDateTime;
317  TimeOffset mTimeOffset;
318 };
319 
325 inline bool operator==(const OffsetDateTime& a, const OffsetDateTime& b) {
326  return a.mLocalDateTime == b.mLocalDateTime
327  && a.mTimeOffset == b.mTimeOffset;
328 }
329 
331 inline bool operator!=(const OffsetDateTime& a, const OffsetDateTime& b) {
332  return ! (a == b);
333 }
334 
335 }
336 
337 #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:69
static TimeOffset forError()
Return an error indicator.
Definition: TimeOffset.h:105
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:75
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:60
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:63
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:138
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:300
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:116
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:56
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.