AceTime  1.11.7
Date and time classes for Arduino that support timezones from the TZ Database.
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 
40  }
41 
57  static OffsetDateTime forComponents(int16_t year, uint8_t month,
58  uint8_t day, uint8_t hour, uint8_t minute, uint8_t second,
59  TimeOffset timeOffset, uint8_t fold = 0) {
62  return OffsetDateTime(ldt, timeOffset);
63  }
64 
75  static OffsetDateTime forEpochSeconds(acetime_t epochSeconds,
76  TimeOffset timeOffset, uint8_t fold = 0) {
77  if (epochSeconds != LocalDate::kInvalidEpochSeconds) {
78  epochSeconds += timeOffset.toSeconds();
79  }
80  auto ldt = LocalDateTime::forEpochSeconds(epochSeconds, fold);
81  return OffsetDateTime(ldt, timeOffset);
82  }
83 
97  int32_t unixSeconds, TimeOffset timeOffset) {
98  acetime_t epochSeconds = (unixSeconds == LocalDate::kInvalidUnixSeconds)
100  : unixSeconds - LocalDate::kSecondsSinceUnixEpoch;
101  return forEpochSeconds(epochSeconds, timeOffset);
102  }
103 
117  int64_t unixSeconds, TimeOffset timeOffset) {
118  acetime_t epochSeconds = (unixSeconds == LocalDate::kInvalidUnixSeconds64
119  || unixSeconds > LocalDate::kMaxValidUnixSeconds64
120  || unixSeconds < LocalDate::kMinValidUnixSeconds64)
122  : (acetime_t) (unixSeconds - LocalDate::kSecondsSinceUnixEpoch);
123  return forEpochSeconds(epochSeconds, timeOffset);
124  }
125 
145  static OffsetDateTime forDateString(const char* dateString);
146 
154  static OffsetDateTime forDateStringChainable(const char*& dateString);
155 
161  static OffsetDateTime forDateString(const __FlashStringHelper* dateString) {
162  // Copy the F() string into a buffer. Use strncpy_P() because ESP32 and
163  // ESP8266 do not have strlcpy_P(). We need +1 for the '\0' character and
164  // another +1 to determine if the dateString is too long to fit.
165  char buffer[kDateStringLength + 2];
166  strncpy_P(buffer, (const char*) dateString, sizeof(buffer));
167  buffer[kDateStringLength + 1] = 0;
168 
169  // check if the original F() was too long
170  size_t len = strlen(buffer);
171  if (len > kDateStringLength) {
172  return forError();
173  }
174 
175  return forDateString(buffer);
176  }
177 
181  }
182 
184  explicit OffsetDateTime() {}
185 
187  bool isError() const {
188  // Check mTimeOffset first because it's expected to be invalid more often.
189  return mTimeOffset.isError() || mLocalDateTime.isError();
190  }
191 
193  int16_t year() const { return mLocalDateTime.year(); }
194 
196  void year(int16_t year) { mLocalDateTime.year(year); }
197 
203  int8_t yearTiny() const { return mLocalDateTime.yearTiny(); }
204 
210  void yearTiny(int8_t yearTiny) { mLocalDateTime.yearTiny(yearTiny); }
211 
213  uint8_t month() const { return mLocalDateTime.month(); }
214 
216  void month(uint8_t month) { mLocalDateTime.month(month); }
217 
219  uint8_t day() const { return mLocalDateTime.day(); }
220 
222  void day(uint8_t day) { mLocalDateTime.day(day); }
223 
225  uint8_t hour() const { return mLocalDateTime.hour(); }
226 
228  void hour(uint8_t hour) { mLocalDateTime.hour(hour); }
229 
231  uint8_t minute() const { return mLocalDateTime.minute(); }
232 
234  void minute(uint8_t minute) { mLocalDateTime.minute(minute); }
235 
237  uint8_t second() const { return mLocalDateTime.second(); }
238 
240  void second(uint8_t second) { mLocalDateTime.second(second); }
241 
243  uint8_t fold() const { return mLocalDateTime.fold(); }
244 
246  void fold(uint8_t fold) { mLocalDateTime.fold(fold); }
247 
249  uint8_t dayOfWeek() const { return mLocalDateTime.dayOfWeek(); }
250 
252  TimeOffset timeOffset() const { return mTimeOffset; }
253 
255  void timeOffset(TimeOffset timeOffset) { mTimeOffset = timeOffset; }
256 
258  const LocalDateTime& localDateTime() const { return mLocalDateTime; }
259 
261  const LocalDate& localDate() const { return mLocalDateTime.localDate(); }
262 
264  const LocalTime& localTime() const { return mLocalDateTime.localTime(); }
265 
271  acetime_t epochSeconds = toEpochSeconds();
272  return OffsetDateTime::forEpochSeconds(epochSeconds, timeOffset);
273  }
274 
279  int32_t toEpochDays() const {
281 
282  int32_t epochDays = mLocalDateTime.localDate().toEpochDays();
283 
284  // Increment or decrement the day count depending on the time offset.
285  acetime_t timeOffset = mLocalDateTime.localTime().toSeconds()
286  - mTimeOffset.toSeconds();
287  if (timeOffset >= 86400) return epochDays + 1;
288  if (timeOffset < 0) return epochDays - 1;
289  return epochDays;
290  }
291 
293  int32_t toUnixDays() const {
294  if (isError()) return LocalDate::kInvalidUnixDays;
296  }
297 
302  acetime_t toEpochSeconds() const {
304  return mLocalDateTime.toEpochSeconds() - mTimeOffset.toSeconds();
305  }
306 
314  int32_t toUnixSeconds() const {
317  }
318 
326  int64_t toUnixSeconds64() const {
329  }
330 
347  int8_t compareTo(const OffsetDateTime& that) const {
348  acetime_t thisSeconds = toEpochSeconds();
349  acetime_t thatSeconds = that.toEpochSeconds();
350  if (thisSeconds < thatSeconds) return -1;
351  if (thisSeconds > thatSeconds) return 1;
352  return 0;
353  }
354 
360  void printTo(Print& printer) const;
361 
362  // Use default copy constructor and assignment operator.
363  OffsetDateTime(const OffsetDateTime&) = default;
364  OffsetDateTime& operator=(const OffsetDateTime&) = default;
365 
366  private:
367  friend bool operator==(const OffsetDateTime& a, const OffsetDateTime& b);
368 
370  static const uint8_t kDateStringLength = 25;
371 
373  explicit OffsetDateTime(const LocalDateTime& ldt, TimeOffset timeOffset):
374  mLocalDateTime(ldt),
375  mTimeOffset(timeOffset) {}
376 
377  LocalDateTime mLocalDateTime;
378  TimeOffset mTimeOffset;
379 };
380 
386 inline bool operator==(const OffsetDateTime& a, const OffsetDateTime& b) {
387  return a.mLocalDateTime == b.mLocalDateTime
388  && a.mTimeOffset == b.mTimeOffset;
389 }
390 
392 inline bool operator!=(const OffsetDateTime& a, const OffsetDateTime& b) {
393  return ! (a == b);
394 }
395 
396 }
397 
398 #endif
Class that holds the date-time as the components (year, month, day, hour, minute, second) without reg...
Definition: LocalDateTime.h:31
static LocalDateTime forEpochSeconds(acetime_t epochSeconds, uint8_t fold=0)
Factory method.
Definition: LocalDateTime.h:75
int8_t yearTiny() const
Return the single-byte year offset from year 2000.
static LocalDateTime forComponents(int16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint8_t fold=0)
Factory method using separated date and time components.
Definition: LocalDateTime.h:45
uint8_t day() const
Return the day of the month.
const LocalDate & localDate() const
Return the LocalDate.
bool isError() const
Return true if any component indicates an error condition.
static LocalDateTime forError()
Factory method that returns an instance where isError() returns true.
uint8_t month() const
Return the month with January=1, December=12.
uint8_t fold() const
Return the fold.
uint8_t second() const
Return the second.
uint8_t minute() const
Return the minute.
const LocalTime & localTime() const
Return the LocalTime.
uint8_t hour() const
Return the hour.
uint8_t dayOfWeek() const
Return the day of the week, Monday=1, Sunday=7 (per ISO 8601).
acetime_t toEpochSeconds() const
Return seconds since AceTime epoch 2000-01-01 00:00:00Z, after assuming that the date and time compon...
int16_t year() const
Return the year.
The date (year, month, day) representing the date without regards to time zone.
Definition: LocalDate.h:36
static const int32_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:45
static const int32_t kInvalidEpochDays
Sentinel epochDays which indicates an error.
Definition: LocalDate.h:66
static const int64_t kMaxValidUnixSeconds64
Maximum 64-bit Unix seconds supported by acetime_t.
Definition: LocalDate.h:81
static const int64_t kInvalidUnixSeconds64
Sentinel 64-bit unixSeconds which indicates an error.
Definition: LocalDate.h:78
static const int32_t kInvalidUnixDays
Sentinel unixDays which indicates an error.
Definition: LocalDate.h:72
static const int64_t kMinValidUnixSeconds64
Minimum 64-bit Unix seconds supported by acetime_t.
Definition: LocalDate.h:85
static const int32_t kInvalidUnixSeconds
Sentinel unixSeconds which indicates an error.
Definition: LocalDate.h:75
static const int32_t kInvalidEpochSeconds
Sentinel epochSeconds which indicates an error.
Definition: LocalDate.h:69
static const int32_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:92
int32_t toEpochDays() const
Return number of days since AceTime epoch (2000-01-01 00:00:00Z).
Definition: LocalDate.h:338
The time (hour, minute, second) fields representing the time without regards to the day or the time z...
Definition: LocalTime.h:27
acetime_t toSeconds() const
Return the number of seconds since midnight.
Definition: LocalTime.h:145
The date (year, month, day), time (hour, minute, second) and offset from UTC (timeOffset).
const LocalTime & localTime() const
Return the LocalTime.
uint8_t day() const
Return the day of the month.
TimeOffset timeOffset() const
Return the offset zone of the OffsetDateTime.
int64_t toUnixSeconds64() const
Return the 64-bit number of seconds from Unix epoch 1970-01-01 00:00:00Z.
static OffsetDateTime forDateStringChainable(const char *&dateString)
Variant of forDateString() that updates the pointer to the next unprocessed character.
void month(uint8_t month)
Set the month.
bool isError() const
Return true if any component indicates an error condition.
const LocalDateTime & localDateTime() const
Return the LocalDateTime.
uint8_t hour() const
Return the hour.
void timeOffset(TimeOffset timeOffset)
Set the offset zone.
OffsetDateTime()
Constructor.
uint8_t month() const
Return the month with January=1, December=12.
void printTo(Print &printer) const
Print OffsetDateTime to 'printer' in ISO 8601 format.
void minute(uint8_t minute)
Set the minute.
static OffsetDateTime forLocalDateTimeAndOffset(const LocalDateTime &localDateTime, TimeOffset timeOffset)
Factory method from LocalDateTime and TimeOffset.
acetime_t toEpochSeconds() const
Return seconds since AceTime epoch (2000-01-01 00:00:00Z), taking into account the offset zone.
static OffsetDateTime forError()
Factory method that returns an instance whose isError() is true.
uint8_t fold() const
Return the fold.
int8_t compareTo(const OffsetDateTime &that) const
Compare 'this' OffsetDateTime with 'that' OffsetDateTime, and return (<0, 0, >0) according to whether...
void hour(uint8_t hour)
Set the hour.
uint8_t minute() const
Return the minute.
OffsetDateTime convertToTimeOffset(TimeOffset timeOffset) const
Create a OffsetDateTime in a different offset zone code (with the same epochSeconds).
int16_t year() const
Return the year.
void yearTiny(int8_t yearTiny)
Set the single-byte year offset from year 2000.
void day(uint8_t day)
Set the day of the month.
int8_t yearTiny() const
Return 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.
static OffsetDateTime forDateString(const char *dateString)
Factory method.
uint8_t dayOfWeek() const
Return the day of the week, Monday=1, Sunday=7 (per ISO 8601).
int32_t toEpochDays() const
Return number of whole days since AceTime epoch (2000-01-01 00:00:00Z), taking into account the offse...
int32_t toUnixDays() const
Return the number of days since Unix epoch (1970-01-01 00:00:00).
static OffsetDateTime forEpochSeconds(acetime_t epochSeconds, TimeOffset timeOffset, uint8_t fold=0)
Factory method.
static OffsetDateTime forDateString(const __FlashStringHelper *dateString)
Factory method.
void year(int16_t year)
Set the year.
void second(uint8_t second)
Set the second.
void fold(uint8_t fold)
Set the fold.
static OffsetDateTime forUnixSeconds64(int64_t unixSeconds, TimeOffset timeOffset)
Factory method that takes the number of seconds (64-bit) since Unix Epoch of 1970-01-01.
int32_t toUnixSeconds() const
Return the number of seconds from Unix epoch 1970-01-01 00:00:00Z.
uint8_t second() const
Return the second.
static OffsetDateTime forUnixSeconds(int32_t unixSeconds, TimeOffset timeOffset)
Factory method that takes the number of seconds since Unix Epoch of 1970-01-01.
static OffsetDateTime forComponents(int16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, TimeOffset timeOffset, uint8_t fold=0)
Factory method using separated date, time, and UTC offset fields.
A thin wrapper that represents a time offset from a reference point, usually 00:00 at UTC,...
Definition: TimeOffset.h:56
static TimeOffset forError()
Return an error indicator.
Definition: TimeOffset.h:105
int32_t toSeconds() const
Return the time offset as seconds.
Definition: TimeOffset.h:116
bool isError() const
Return true if this TimeOffset represents an error.
Definition: TimeOffset.h:138