AceTime  1.11.7
Date and time classes for Arduino that support timezones from the TZ Database.
LocalDateTime.h
1 /*
2  * MIT License
3  * Copyright (c) 2018 Brian T. Park
4  */
5 
6 #ifndef ACE_TIME_LOCAL_DATE_TIME_H
7 #define ACE_TIME_LOCAL_DATE_TIME_H
8 
9 #include <stddef.h> // size_t
10 #include <stdint.h> // uint8_t, etc
11 #include <string.h> // strlen()
12 #include <Arduino.h> // strncpy_P()
13 #include "LocalDate.h"
14 #include "LocalTime.h"
15 
16 class Print;
17 class __FlashStringHelper;
18 
19 namespace ace_time {
20 
32  public:
33 
45  static LocalDateTime forComponents(int16_t year, uint8_t month,
46  uint8_t day, uint8_t hour, uint8_t minute, uint8_t second,
47  uint8_t fold = 0) {
51  return forTinyComponents(
53  }
54 
57  uint8_t day, uint8_t hour, uint8_t minute, uint8_t second,
58  uint8_t fold = 0) {
59  return LocalDateTime(
62  }
63 
76  acetime_t epochSeconds, uint8_t fold = 0) {
77 
78  LocalDate ld;
79  LocalTime lt;
80  if (epochSeconds == LocalDate::kInvalidEpochSeconds) {
81  ld = LocalDate::forError();
82  lt = LocalTime::forError();
83  } else {
84  // Integer floor-division towards -infinity
85  acetime_t days = (epochSeconds < 0)
86  ? (epochSeconds + 1) / 86400 - 1
87  : epochSeconds / 86400;
88 
89  // Avoid % operator, because it's slow on an 8-bit process and because
90  // epochSeconds could be negative.
91  acetime_t seconds = epochSeconds - 86400 * days;
92  ld = LocalDate::forEpochDays(days);
93  lt = LocalTime::forSeconds(seconds, fold);
94  }
95 
96  return LocalDateTime(ld, lt);
97  }
98 
106  static LocalDateTime forUnixSeconds(int32_t unixSeconds) {
107  acetime_t epochSeconds = (unixSeconds == LocalDate::kInvalidUnixSeconds)
109  : unixSeconds - LocalDate::kSecondsSinceUnixEpoch;
110  return forEpochSeconds(epochSeconds);
111  }
112 
120  static LocalDateTime forUnixSeconds64(int64_t unixSeconds) {
121  acetime_t epochSeconds = (unixSeconds == LocalDate::kInvalidUnixSeconds64
122  || unixSeconds > LocalDate::kMaxValidUnixSeconds64
123  || unixSeconds < LocalDate::kMinValidUnixSeconds64)
125  : (acetime_t) (unixSeconds - LocalDate::kSecondsSinceUnixEpoch);
126  return forEpochSeconds(epochSeconds);
127  }
128 
145  static LocalDateTime forDateString(const char* dateString);
146 
154  static LocalDateTime forDateStringChainable(const char*& dateString);
155 
160  static LocalDateTime forDateString(const __FlashStringHelper* dateString) {
161  // Copy the F() string into a buffer. Use strncpy_P() because ESP32 and
162  // ESP8266 do not have strlcpy_P(). We need +1 for the '\0' character and
163  // another +1 to determine if the dateString is too long to fit.
164  char buffer[kDateTimeStringLength + 2];
165  strncpy_P(buffer, (const char*) dateString, sizeof(buffer));
166  buffer[kDateTimeStringLength + 1] = 0;
167 
168  // check if the original F() was too long
169  size_t len = strlen(buffer);
170  if (len > kDateTimeStringLength) {
171  return forError();
172  }
173 
174  return forDateString(buffer);
175  }
176 
180  }
181 
183  explicit LocalDateTime() {}
184 
186  bool isError() const {
187  return mLocalDate.isError() || mLocalTime.isError();
188  }
189 
191  int16_t year() const { return mLocalDate.year(); }
192 
194  void year(int16_t year) { mLocalDate.year(year); }
195 
201  int8_t yearTiny() const { return mLocalDate.yearTiny(); }
202 
208  void yearTiny(int8_t yearTiny) { mLocalDate.yearTiny(yearTiny); }
209 
211  uint8_t month() const { return mLocalDate.month(); }
212 
214  void month(uint8_t month) { mLocalDate.month(month); }
215 
217  uint8_t day() const { return mLocalDate.day(); }
218 
220  void day(uint8_t day) { mLocalDate.day(day); }
221 
223  uint8_t hour() const { return mLocalTime.hour(); }
224 
226  void hour(uint8_t hour) { mLocalTime.hour(hour); }
227 
229  uint8_t minute() const { return mLocalTime.minute(); }
230 
232  void minute(uint8_t minute) { mLocalTime.minute(minute); }
233 
235  uint8_t second() const { return mLocalTime.second(); }
236 
238  void second(uint8_t second) { mLocalTime.second(second); }
239 
241  uint8_t fold() const { return mLocalTime.fold(); }
242 
244  void fold(uint8_t fold) { mLocalTime.fold(fold); }
245 
247  uint8_t dayOfWeek() const { return mLocalDate.dayOfWeek(); }
248 
250  const LocalDate& localDate() const { return mLocalDate; }
251 
253  const LocalTime& localTime() const { return mLocalTime; }
254 
258  int32_t toEpochDays() const {
260  return mLocalDate.toEpochDays();
261  }
262 
264  int32_t toUnixDays() const {
265  if (isError()) return LocalDate::kInvalidUnixDays;
267  }
268 
274  acetime_t toEpochSeconds() const {
276 
277  int32_t days = mLocalDate.toEpochDays();
278  acetime_t seconds = mLocalTime.toSeconds();
279  return days * 86400 + seconds;
280  }
281 
290  int32_t toUnixSeconds() const {
293  }
294 
303  int64_t toUnixSeconds64() const {
306  }
307 
314  int8_t compareTo(const LocalDateTime& that) const {
315  int8_t dateCompare = localDate().compareTo(that.localDate());
316  if (dateCompare != 0) return dateCompare;
317  int8_t timeCompare = localTime().compareTo(that.localTime());
318  if (timeCompare != 0) return timeCompare;
319  return 0;
320  }
321 
327  void printTo(Print& printer) const;
328 
329  // Use default copy constructor and assignment operator.
330  LocalDateTime(const LocalDateTime&) = default;
331  LocalDateTime& operator=(const LocalDateTime&) = default;
332 
333  private:
334  friend bool operator==(const LocalDateTime& a, const LocalDateTime& b);
335 
337  static const uint8_t kDateTimeStringLength = 19;
338 
340  explicit LocalDateTime(const LocalDate& ld, const LocalTime& lt):
341  mLocalDate(ld),
342  mLocalTime(lt) {}
343 
344  LocalDate mLocalDate;
345  LocalTime mLocalTime;
346 };
347 
353 inline bool operator==(const LocalDateTime& a, const LocalDateTime& b) {
354  return a.mLocalDate == b.mLocalDate
355  && a.mLocalTime == b.mLocalTime;
356 }
357 
359 inline bool operator!=(const LocalDateTime& a, const LocalDateTime& b) {
360  return ! (a == b);
361 }
362 
363 }
364 
365 #endif
Class that holds the date-time as the components (year, month, day, hour, minute, second) without reg...
Definition: LocalDateTime.h:31
static LocalDateTime forDateString(const __FlashStringHelper *dateString)
Factory method.
int64_t toUnixSeconds64() const
Return 64-bit seconds from Unix epoch 1970-01-01 00:00:00Z, after assuming that the date and time com...
void hour(uint8_t hour)
Set the hour.
void printTo(Print &printer) const
Print LocalDateTime to 'printer' in ISO 8601 format.
static LocalDateTime forEpochSeconds(acetime_t epochSeconds, uint8_t fold=0)
Factory method.
Definition: LocalDateTime.h:75
LocalDateTime()
Constructor.
void fold(uint8_t fold)
Set the fold.
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
void minute(uint8_t minute)
Set the minute.
uint8_t day() const
Return the day of the month.
int32_t toUnixSeconds() const
Return seconds from Unix epoch 1970-01-01 00:00:00Z, after assuming that the date and time components...
const LocalDate & localDate() const
Return the LocalDate.
void yearTiny(int8_t yearTiny)
Set the single-byte year offset from year 2000.
bool isError() const
Return true if any component indicates an error condition.
int8_t compareTo(const LocalDateTime &that) const
Compare 'this' LocalDateTime with 'that' LocalDateTime, and return (<0, 0, >0) according to whether '...
void month(uint8_t month)
Set the month.
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.
static LocalDateTime forDateString(const char *dateString)
Factory method.
uint8_t second() const
Return the second.
void day(uint8_t day)
Set the day of the month.
uint8_t minute() const
Return the minute.
void year(int16_t year)
Set the year.
static LocalDateTime forUnixSeconds64(int64_t unixSeconds)
Factory method that takes the 64-bit number of seconds since Unix Epoch of 1970-01-01.
static LocalDateTime forUnixSeconds(int32_t unixSeconds)
Factory method that takes the number of seconds since Unix Epoch of 1970-01-01.
int32_t toUnixDays() const
Return the number of days since Unix epoch (1970-01-01 00:00:00).
const LocalTime & localTime() const
Return the LocalTime.
static LocalDateTime forTinyComponents(int8_t yearTiny, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint8_t fold=0)
Factory method using components with an int8_t yearTiny.
Definition: LocalDateTime.h:56
int32_t toEpochDays() const
Return number of whole days since AceTime epoch (2000-01-01 00:00:00Z).
uint8_t hour() const
Return the hour.
static LocalDateTime forDateStringChainable(const char *&dateString)
Variant of forDateString() that updates the pointer to the next unprocessed character.
uint8_t dayOfWeek() const
Return the day of the week, Monday=1, Sunday=7 (per ISO 8601).
friend bool operator==(const LocalDateTime &a, const LocalDateTime &b)
Return true if two LocalDateTime objects are equal in all components.
void second(uint8_t second)
Set the second.
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 int16_t kEpochYear
Base year of epoch.
Definition: LocalDate.h:39
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
bool isError() const
Return true if any component indicates an error condition.
Definition: LocalDate.h:316
static LocalDate forError()
Factory method that returns a LocalDate which represents an error condition.
Definition: LocalDate.h:244
static const int64_t kMaxValidUnixSeconds64
Maximum 64-bit Unix seconds supported by acetime_t.
Definition: LocalDate.h:81
int8_t yearTiny() const
Return the single-byte year offset from year 2000.
Definition: LocalDate.h:279
static const int64_t kInvalidUnixSeconds64
Sentinel 64-bit unixSeconds which indicates an error.
Definition: LocalDate.h:78
uint8_t dayOfWeek() const
Calculate the day of week given the (year, month, day).
Definition: LocalDate.h:306
static const int32_t kInvalidUnixDays
Sentinel unixDays which indicates an error.
Definition: LocalDate.h:72
int8_t compareTo(const LocalDate &that) const
Compare 'this' LocalDate to 'that' LocalDate, returning (<0, 0, >0) according to whether 'this' occur...
Definition: LocalDate.h:405
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 bool isYearValid(int16_t year)
Return true if year is within valid range of [1873, 2127].
Definition: LocalDate.h:254
static const int32_t kInvalidEpochSeconds
Sentinel epochSeconds which indicates an error.
Definition: LocalDate.h:69
int16_t year() const
Return the full year instead of just the last 2 digits.
Definition: LocalDate.h:269
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
static const int8_t kInvalidYearTiny
Sentinel yearTiny which indicates an error condition or sometimes a year that 'does not exist'.
Definition: LocalDate.h:51
static LocalDate forTinyComponents(int8_t yearTiny, uint8_t month, uint8_t day)
Factory method using components with an int8_t yearTiny.
Definition: LocalDate.h:131
static LocalDate forEpochDays(int32_t epochDays)
Factory method using the number of days since AceTime epoch of 2000-01-01.
Definition: LocalDate.h:143
uint8_t month() const
Return the month with January=1, December=12.
Definition: LocalDate.h:289
uint8_t day() const
Return the day of the month.
Definition: LocalDate.h:295
The time (hour, minute, second) fields representing the time without regards to the day or the time z...
Definition: LocalTime.h:27
static LocalTime forComponents(uint8_t hour, uint8_t minute, uint8_t second, uint8_t fold=0)
Factory method using separated date, time, and time zone fields.
Definition: LocalTime.h:43
uint8_t fold() const
Return the fold.
Definition: LocalTime.h:136
acetime_t toSeconds() const
Return the number of seconds since midnight.
Definition: LocalTime.h:145
static LocalTime forError()
Factory method that returns an instance which indicates an error condition.
Definition: LocalTime.h:95
uint8_t hour() const
Return the hour.
Definition: LocalTime.h:118
uint8_t minute() const
Return the minute.
Definition: LocalTime.h:124
static LocalTime forSeconds(acetime_t seconds, uint8_t fold=0)
Factory method.
Definition: LocalTime.h:56
uint8_t second() const
Return the second.
Definition: LocalTime.h:130
bool isError() const
Return true if any component is outside the normal time range of 00:00:00 to 23:59:59.
Definition: LocalTime.h:108
int8_t compareTo(const LocalTime &that) const
Compare 'this' LocalTime with 'that' LocalTime, and return (<0, 0, >0) according to whether 'this' oc...
Definition: LocalTime.h:162