COSA
An Object-Oriented Platform for Arduino Programming
Time.hh
Go to the documentation of this file.
1 
21 #ifndef COSA_TIME_HH
22 #define COSA_TIME_HH
23 
24 #include "Cosa/Types.h"
25 #include "Cosa/BCD.h"
26 #include "Cosa/IOStream.hh"
27 
28 // Weekday numbers (1..7)
29 enum {
30  SUNDAY = 1,
31  MONDAY = 2,
32  TUESDAY = 3,
33  WEDNESDAY = 4,
34  THURSDAY = 5,
35  FRIDAY = 6,
37 };
38 
39 // NTP epoch year and weekday (Monday)
40 const uint16_t NTP_EPOCH_YEAR = 1900;
41 const uint8_t NTP_EPOCH_WEEKDAY = MONDAY;
42 
43 // POSIX epoch year and weekday (Thursday)
44 const uint16_t POSIX_EPOCH_YEAR = 1970;
45 const uint8_t POSIX_EPOCH_WEEKDAY = THURSDAY;
46 
47 // Y2K epoch year and weekday (Saturday)
48 const uint16_t Y2K_EPOCH_YEAR = 2000;
49 const uint8_t Y2K_EPOCH_WEEKDAY = SATURDAY;
50 
55 typedef uint32_t clock_t;
56 
57 const uint32_t SECONDS_PER_DAY = 86400L;
58 const uint16_t SECONDS_PER_HOUR = 3600;
59 const uint8_t SECONDS_PER_MINUTE = 60;
60 const uint8_t DAYS_PER_WEEK = 7;
61 
62 #if (ARDUINO > 150)
63 
68 constexpr clock_t operator "" _h(unsigned long long h)
69 {
70  return (h * SECONDS_PER_HOUR);
71 }
72 
78 constexpr clock_t operator "" _min(unsigned long long min)
79 {
80  return (min * SECONDS_PER_MINUTE);
81 }
82 
88 constexpr clock_t operator "" _s(unsigned long long s)
89 {
90  return (s);
91 }
92 #endif
93 
102 struct time_t {
103  uint8_t seconds;
104  uint8_t minutes;
105  uint8_t hours;
106  uint8_t day;
107  uint8_t date;
108  uint8_t month;
109  uint8_t year;
110 
115  void to_binary()
116  __attribute__((always_inline))
117  {
118  ::to_binary(&seconds, sizeof(time_t));
119  }
120 
125  void to_bcd()
126  __attribute__((always_inline))
127  {
128  ::to_bcd(&seconds, sizeof(time_t));
129  }
130 
134  time_t() {}
135 
141  time_t(clock_t c, int8_t zone = 0);
142 
147  operator clock_t() const;
148 
152  void set_day()
153  {
154  day = weekday_for(days());
155  }
156 
161  uint16_t days() const;
162 
167  uint16_t day_of_year() const;
168 
173  uint16_t full_year() const
174  {
175  return full_year(year);
176  }
177 
183  static uint16_t full_year(uint8_t year)
184  {
185  uint16_t y = year;
186 
187  if (y < pivot_year)
188  y += 100 * (epoch_year()/100 + 1);
189  else
190  y += 100 * (epoch_year()/100);
191 
192  return y;
193  }
194 
199  bool is_leap() const
200  {
201  return is_leap(full_year());
202  }
203 
209  static bool is_leap(uint16_t year)
210  {
211  if (year % 4) return false;
212  uint16_t y = year % 400;
213  return (y == 0) || ((y != 100) && (y != 200) && (y != 300));
214  }
215 
221  static uint16_t days_per(uint16_t year)
222  {
223  return (365 + is_leap(year));
224  }
225 
231  static uint8_t weekday_for(uint16_t dayno)
232  {
233  return ((dayno+epoch_weekday-1) % DAYS_PER_WEEK) + 1;
234  }
235 
240  bool is_valid() const
241  {
242  return
243  ((year <= 99) &&
244  (1 <= month) && (month <= 12) &&
245  ((1 <= date) &&
246  ((date <= pgm_read_byte(&days_in[month])) ||
247  ((month == 2) && is_leap() && (date == 29)))) &&
248  (1 <= day) && (day <= 7) &&
249  (hours <= 23) &&
250  (minutes <= 59) &&
251  (seconds <= 59));
252  }
253 
262  static void epoch_year(uint16_t y)
263  {
264  s_epoch_year = y;
265  epoch_offset = s_epoch_year % 100;
267  }
268 
273  static uint16_t epoch_year()
274  {
275  return (s_epoch_year);
276  }
277 
278  static uint8_t epoch_weekday;
279 
285  static uint8_t pivot_year;
286 
292  static void use_fastest_epoch();
293 
299  bool parse(str_P s);
300 
304  static const uint8_t days_in[] PROGMEM;
305 
306 protected:
307  static uint16_t s_epoch_year;
308  static uint8_t epoch_offset;
309 } __attribute__((packed));
310 
318 IOStream& operator<<(IOStream& outs, const time_t& t);
319 
320 #endif
const uint8_t POSIX_EPOCH_WEEKDAY
Definition: Time.hh:45
Definition: Time.hh:34
static const uint8_t days_in[]
Definition: Time.hh:304
Definition: Time.hh:30
const uint16_t Y2K_EPOCH_YEAR
Definition: Time.hh:48
uint8_t minutes
00-59 Minutes.
Definition: Time.hh:104
Definition: Time.hh:35
static uint16_t epoch_year()
Definition: Time.hh:273
static uint8_t pivot_year
Definition: Time.hh:285
uint8_t day
01-07 Day.
Definition: Time.hh:106
bool parse(str_P s)
Definition: Time.cpp:40
static uint16_t full_year(uint8_t year)
Definition: Time.hh:183
uint16_t days() const
Definition: Time.cpp:140
bool is_leap() const
Definition: Time.hh:199
uint32_t clock_t
Definition: Time.hh:55
uint8_t month
01-12 Month.
Definition: Time.hh:108
time_t()
Definition: Time.hh:134
static uint16_t days_per(uint16_t year)
Definition: Time.hh:221
const uint8_t Y2K_EPOCH_WEEKDAY
Definition: Time.hh:49
const uint16_t NTP_EPOCH_YEAR
Definition: Time.hh:40
static uint8_t epoch_weekday
Definition: Time.hh:278
const class prog_str * str_P
Definition: Types.h:187
const uint32_t SECONDS_PER_DAY
Definition: Time.hh:57
IOStream & operator<<(IOStream &outs, const time_t &t)
Definition: Time.cpp:23
const uint8_t SECONDS_PER_MINUTE
Definition: Time.hh:59
void set_day()
Definition: Time.hh:152
Definition: Time.hh:36
uint8_t year
00-99 Year.
Definition: Time.hh:109
uint8_t seconds
00-59 Seconds.
Definition: Time.hh:103
Definition: Time.hh:102
const uint16_t POSIX_EPOCH_YEAR
Definition: Time.hh:44
const uint8_t DAYS_PER_WEEK
Definition: Time.hh:60
bool is_valid() const
Definition: Time.hh:240
static void use_fastest_epoch()
Definition: Time.cpp:164
uint8_t hours
00-23 Hours.
Definition: Time.hh:105
static bool is_leap(uint16_t year)
Definition: Time.hh:209
Definition: Time.hh:31
static uint8_t epoch_offset
Definition: Time.hh:308
uint8_t date
01-31 Date.
Definition: Time.hh:107
uint16_t full_year() const
Definition: Time.hh:173
Definition: Time.hh:32
uint16_t day_of_year() const
Definition: Time.cpp:151
void to_binary()
Definition: Time.hh:115
const uint8_t NTP_EPOCH_WEEKDAY
Definition: Time.hh:41
static void epoch_year(uint16_t y)
Definition: Time.hh:262
void to_bcd()
Definition: Time.hh:125
static uint8_t weekday_for(uint16_t dayno)
Definition: Time.hh:231
static uint16_t s_epoch_year
Definition: Time.hh:307
const uint16_t SECONDS_PER_HOUR
Definition: Time.hh:58