AceTime  1.7.4
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.
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 
31  public:
32 
43  static LocalDateTime forComponents(int16_t year, uint8_t month,
44  uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) {
49  }
50 
53  uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) {
54  return LocalDateTime(
57  }
58 
70  static LocalDateTime forEpochSeconds(acetime_t epochSeconds) {
71  LocalDate ld;
72  LocalTime lt;
73  if (epochSeconds == LocalDate::kInvalidEpochSeconds) {
74  ld = LocalDate::forError();
75  lt = LocalTime::forError();
76  } else {
77  // Integer floor-division towards -infinity
78  acetime_t days = (epochSeconds < 0)
79  ? (epochSeconds + 1) / 86400 - 1
80  : epochSeconds / 86400;
81 
82  // Avoid % operator, because it's slow on an 8-bit process and because
83  // epochSeconds could be negative.
84  acetime_t seconds = epochSeconds - 86400 * days;
85  ld = LocalDate::forEpochDays(days);
86  lt = LocalTime::forSeconds(seconds);
87  }
88 
89  return LocalDateTime(ld, lt);
90  }
91 
99  static LocalDateTime forUnixSeconds(acetime_t unixSeconds) {
100  acetime_t epochSeconds = (unixSeconds == LocalDate::kInvalidEpochSeconds)
101  ? unixSeconds
102  : unixSeconds - LocalDate::kSecondsSinceUnixEpoch;
103  return forEpochSeconds(epochSeconds);
104  }
105 
122  static LocalDateTime forDateString(const char* dateString);
123 
131  static LocalDateTime forDateStringChainable(const char*& dateString);
132 
137  static LocalDateTime forDateString(const __FlashStringHelper* dateString) {
138  // Copy the F() string into a buffer. Use strncpy_P() because ESP32 and
139  // ESP8266 do not have strlcpy_P(). We need +1 for the '\0' character and
140  // another +1 to determine if the dateString is too long to fit.
141  char buffer[kDateTimeStringLength + 2];
142  strncpy_P(buffer, (const char*) dateString, sizeof(buffer));
143  buffer[kDateTimeStringLength + 1] = 0;
144 
145  // check if the original F() was too long
146  size_t len = strlen(buffer);
147  if (len > kDateTimeStringLength) {
148  return forError();
149  }
150 
151  return forDateString(buffer);
152  }
153 
157  }
158 
160  explicit LocalDateTime() {}
161 
163  bool isError() const {
164  return mLocalDate.isError() || mLocalTime.isError();
165  }
166 
168  int16_t year() const { return mLocalDate.year(); }
169 
171  void year(int16_t year) { mLocalDate.year(year); }
172 
178  int8_t yearTiny() const { return mLocalDate.yearTiny(); }
179 
185  void yearTiny(int8_t yearTiny) { mLocalDate.yearTiny(yearTiny); }
186 
188  uint8_t month() const { return mLocalDate.month(); }
189 
191  void month(uint8_t month) { mLocalDate.month(month); }
192 
194  uint8_t day() const { return mLocalDate.day(); }
195 
197  void day(uint8_t day) { mLocalDate.day(day); }
198 
200  uint8_t hour() const { return mLocalTime.hour(); }
201 
203  void hour(uint8_t hour) { mLocalTime.hour(hour); }
204 
206  uint8_t minute() const { return mLocalTime.minute(); }
207 
209  void minute(uint8_t minute) { mLocalTime.minute(minute); }
210 
212  uint8_t second() const { return mLocalTime.second(); }
213 
215  void second(uint8_t second) { mLocalTime.second(second); }
216 
218  uint8_t dayOfWeek() const { return mLocalDate.dayOfWeek(); }
219 
221  const LocalDate& localDate() const { return mLocalDate; }
222 
224  const LocalTime& localTime() const { return mLocalTime; }
225 
229  acetime_t toEpochDays() const {
231  return mLocalDate.toEpochDays();
232  }
233 
235  acetime_t toUnixDays() const {
238  }
239 
245  acetime_t toEpochSeconds() const {
247 
248  acetime_t days = mLocalDate.toEpochDays();
249  acetime_t seconds = mLocalTime.toSeconds();
250  return days * 86400 + seconds;
251  }
252 
261  acetime_t toUnixSeconds() const {
264  }
265 
272  int8_t compareTo(const LocalDateTime& that) const {
273  int8_t dateCompare = localDate().compareTo(that.localDate());
274  if (dateCompare != 0) return dateCompare;
275  int8_t timeCompare = localTime().compareTo(that.localTime());
276  if (timeCompare != 0) return timeCompare;
277  return 0;
278  }
279 
285  void printTo(Print& printer) const;
286 
287  // Use default copy constructor and assignment operator.
288  LocalDateTime(const LocalDateTime&) = default;
289  LocalDateTime& operator=(const LocalDateTime&) = default;
290 
291  private:
292  friend bool operator==(const LocalDateTime& a, const LocalDateTime& b);
293 
295  static const uint8_t kDateTimeStringLength = 19;
296 
298  explicit LocalDateTime(const LocalDate& ld, const LocalTime& lt):
299  mLocalDate(ld),
300  mLocalTime(lt) {}
301 
302  LocalDate mLocalDate;
303  LocalTime mLocalTime;
304 };
305 
311 inline bool operator==(const LocalDateTime& a, const LocalDateTime& b) {
312  return a.mLocalDate == b.mLocalDate
313  && a.mLocalTime == b.mLocalTime;
314 }
315 
317 inline bool operator!=(const LocalDateTime& a, const LocalDateTime& b) {
318  return ! (a == b);
319 }
320 
321 }
322 
323 #endif
ace_time::LocalDateTime::toUnixDays
acetime_t toUnixDays() const
Return the number of days since Unix epoch (1970-01-01 00:00:00).
Definition: LocalDateTime.h:235
ace_time::LocalDateTime::day
void day(uint8_t day)
Set the day of the month.
Definition: LocalDateTime.h:197
ace_time::LocalDate::forError
static LocalDate forError()
Factory method that returns a LocalDate which represents an error condition.
Definition: LocalDate.h:206
ace_time::LocalDateTime::yearTiny
void yearTiny(int8_t yearTiny)
Set the single-byte year offset from year 2000.
Definition: LocalDateTime.h:185
ace_time::LocalDate::kSecondsSinceUnixEpoch
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
ace_time::LocalDateTime::dayOfWeek
uint8_t dayOfWeek() const
Return the day of the week, Monday=1, Sunday=7 (per ISO 8601).
Definition: LocalDateTime.h:218
ace_time::LocalDate::forEpochDays
static LocalDate forEpochDays(acetime_t epochDays)
Factory method using the number of days since AceTime epoch of 2000-01-01.
Definition: LocalDate.h:125
ace_time::LocalDateTime::forUnixSeconds
static LocalDateTime forUnixSeconds(acetime_t unixSeconds)
Factory method that takes the number of seconds since Unix Epoch of 1970-01-01.
Definition: LocalDateTime.h:99
ace_time::LocalDate::month
uint8_t month() const
Return the month with January=1, December=12.
Definition: LocalDate.h:251
ace_time::LocalDateTime::hour
uint8_t hour() const
Return the hour.
Definition: LocalDateTime.h:200
ace_time::LocalDate::kInvalidEpochSeconds
static const acetime_t kInvalidEpochSeconds
Sentinel epochSeconds which indicates an error.
Definition: LocalDate.h:63
ace_time::LocalDateTime::forTinyComponents
static LocalDateTime forTinyComponents(int8_t yearTiny, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)
Factory method using components with an int8_t yearTiny.
Definition: LocalDateTime.h:52
ace_time::LocalDateTime
Class that holds the date-time as the components (year, month, day, hour, minute, second) without reg...
Definition: LocalDateTime.h:30
ace_time::LocalDate::kInvalidEpochDays
static const acetime_t kInvalidEpochDays
Sentinel epochDays which indicates an error.
Definition: LocalDate.h:60
ace_time::LocalDate::toEpochDays
acetime_t toEpochDays() const
Return number of days since AceTime epoch (2000-01-01 00:00:00Z).
Definition: LocalDate.h:300
ace_time::LocalDateTime::printTo
void printTo(Print &printer) const
Print LocalDateTime to 'printer' in ISO 8601 format.
Definition: LocalDateTime.cpp:14
ace_time::LocalDate::dayOfWeek
uint8_t dayOfWeek() const
Calculate the day of week given the (year, month, day).
Definition: LocalDate.h:268
ace_time::LocalDateTime::forError
static LocalDateTime forError()
Factory method that returns an instance where isError() returns true.
Definition: LocalDateTime.h:155
ace_time::LocalDateTime::month
void month(uint8_t month)
Set the month.
Definition: LocalDateTime.h:191
ace_time::LocalDate
The date (year, month, day) representing the date without regards to time zone.
Definition: LocalDate.h:36
ace_time::LocalDateTime::toEpochDays
acetime_t toEpochDays() const
Return number of whole days since AceTime epoch (2000-01-01 00:00:00Z).
Definition: LocalDateTime.h:229
ace_time::LocalDateTime::minute
void minute(uint8_t minute)
Set the minute.
Definition: LocalDateTime.h:209
ace_time::LocalDateTime::second
void second(uint8_t second)
Set the second.
Definition: LocalDateTime.h:215
ace_time::LocalDateTime::forComponents
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:43
ace_time::LocalDateTime::month
uint8_t month() const
Return the month with January=1, December=12.
Definition: LocalDateTime.h:188
ace_time::LocalDateTime::operator==
friend bool operator==(const LocalDateTime &a, const LocalDateTime &b)
Return true if two LocalDateTime objects are equal in all components.
Definition: LocalDateTime.h:311
ace_time::LocalTime::isError
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:106
ace_time::LocalDate::kInvalidYearTiny
static const int8_t kInvalidYearTiny
Sentinel yearTiny which indicates an error condition or sometimes a year that 'does not exist'.
Definition: LocalDate.h:45
ace_time::LocalTime::forError
static LocalTime forError()
Factory method that returns an instance which indicates an error condition.
Definition: LocalTime.h:93
ace_time::LocalDateTime::forDateStringChainable
static LocalDateTime forDateStringChainable(const char *&dateString)
Variant of forDateString() that updates the pointer to the next unprocessed character.
Definition: LocalDateTime.cpp:46
ace_time::LocalDateTime::second
uint8_t second() const
Return the second.
Definition: LocalDateTime.h:212
ace_time::LocalDate::day
uint8_t day() const
Return the day of the month.
Definition: LocalDate.h:257
ace_time::LocalDateTime::hour
void hour(uint8_t hour)
Set the hour.
Definition: LocalDateTime.h:203
ace_time::LocalDateTime::localTime
const LocalTime & localTime() const
Return the LocalTime.
Definition: LocalDateTime.h:224
ace_time::LocalDateTime::isError
bool isError() const
Return true if any component indicates an error condition.
Definition: LocalDateTime.h:163
ace_time::LocalDateTime::minute
uint8_t minute() const
Return the minute.
Definition: LocalDateTime.h:206
ace_time::LocalDateTime::localDate
const LocalDate & localDate() const
Return the LocalDate.
Definition: LocalDateTime.h:221
ace_time::LocalDate::forTinyComponents
static LocalDate forTinyComponents(int8_t yearTiny, uint8_t month, uint8_t day)
Factory method using components with an int8_t yearTiny.
Definition: LocalDate.h:113
ace_time::LocalDate::isError
bool isError() const
Return true if any component indicates an error condition.
Definition: LocalDate.h:278
ace_time::LocalDate::year
int16_t year() const
Return the full year instead of just the last 2 digits.
Definition: LocalDate.h:231
ace_time::LocalDateTime::toEpochSeconds
acetime_t toEpochSeconds() const
Return seconds since AceTime epoch 2000-01-01 00:00:00Z, after assuming that the date and time compon...
Definition: LocalDateTime.h:245
ace_time::LocalDate::kEpochYear
static const int16_t kEpochYear
Base year of epoch.
Definition: LocalDate.h:39
ace_time::LocalDateTime::year
int16_t year() const
Return the year.
Definition: LocalDateTime.h:168
ace_time::LocalDateTime::yearTiny
int8_t yearTiny() const
Return the single-byte year offset from year 2000.
Definition: LocalDateTime.h:178
ace_time::LocalDateTime::compareTo
int8_t compareTo(const LocalDateTime &that) const
Compare 'this' LocalDateTime with 'that' LocalDateTime, and return (<0, 0, >0) according to whether '...
Definition: LocalDateTime.h:272
ace_time::LocalDateTime::LocalDateTime
LocalDateTime()
Constructor.
Definition: LocalDateTime.h:160
ace_time::LocalTime::hour
uint8_t hour() const
Return the hour.
Definition: LocalTime.h:116
ace_time::LocalDate::compareTo
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:359
ace_time::LocalTime::second
uint8_t second() const
Return the second.
Definition: LocalTime.h:128
ace_time::LocalTime::toSeconds
acetime_t toSeconds() const
Return the number of seconds since midnight.
Definition: LocalTime.h:137
ace_time::LocalDateTime::toUnixSeconds
acetime_t toUnixSeconds() const
Return seconds from Unix epoch 1970-01-01 00:00:00Z, after assuming that the date and time components...
Definition: LocalDateTime.h:261
ace_time::LocalTime::minute
uint8_t minute() const
Return the minute.
Definition: LocalTime.h:122
ace_time::LocalDateTime::forDateString
static LocalDateTime forDateString(const char *dateString)
Factory method.
Definition: LocalDateTime.cpp:38
ace_time::LocalDateTime::year
void year(int16_t year)
Set the year.
Definition: LocalDateTime.h:171
ace_time::LocalDateTime::day
uint8_t day() const
Return the day of the month.
Definition: LocalDateTime.h:194
ace_time::LocalTime::forComponents
static LocalTime forComponents(uint8_t hour, uint8_t minute, uint8_t second)
Factory method using separated date, time, and time zone fields.
Definition: LocalTime.h:41
ace_time::LocalTime::compareTo
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:152
ace_time::LocalDate::kDaysSinceUnixEpoch
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
ace_time::LocalDate::isYearValid
static bool isYearValid(int16_t year)
Return true if year is within valid range of [1873, 2127].
Definition: LocalDate.h:216
ace_time::LocalDateTime::forEpochSeconds
static LocalDateTime forEpochSeconds(acetime_t epochSeconds)
Factory method.
Definition: LocalDateTime.h:70
ace_time::LocalTime
The time (hour, minute, second) fields representing the time without regards to the day or the time z...
Definition: LocalTime.h:26
ace_time::LocalDate::yearTiny
int8_t yearTiny() const
Return the single-byte year offset from year 2000.
Definition: LocalDate.h:241
ace_time::LocalTime::forSeconds
static LocalTime forSeconds(acetime_t seconds)
Factory method.
Definition: LocalTime.h:54
ace_time::LocalDateTime::forDateString
static LocalDateTime forDateString(const __FlashStringHelper *dateString)
Factory method.
Definition: LocalDateTime.h:137