AceTime  1.9.0
Date and time classes for Arduino that support timezones from the TZ Database.
ZoneProcessor.cpp
1 /*
2  * MIT License
3  * Copyright (c) 2019 Brian T. Park
4  */
5 
6 #include "ZoneProcessor.h"
7 
8 namespace ace_time {
9 namespace internal {
10 
11 MonthDay calcStartDayOfMonth(int16_t year, uint8_t month,
12  uint8_t onDayOfWeek, int8_t onDayOfMonth) {
13  if (onDayOfWeek == 0) return {month, (uint8_t) onDayOfMonth};
14 
15  if (onDayOfMonth >= 0) {
16  // Convert "last{Xxx}" to "last{Xxx}>={daysInMonth-6}".
17  uint8_t daysInMonth = LocalDate::daysInMonth(year, month);
18  if (onDayOfMonth == 0) {
19  onDayOfMonth = daysInMonth - 6;
20  }
21 
22  auto limitDate = LocalDate::forComponents(year, month, onDayOfMonth);
23  uint8_t dayOfWeekShift = (onDayOfWeek - limitDate.dayOfWeek() + 7) % 7;
24  uint8_t day = (uint8_t) (onDayOfMonth + dayOfWeekShift);
25  if (day > daysInMonth) {
26  // TODO: Support shifting from Dec to Jan of following year.
27  day -= daysInMonth;
28  month++;
29  }
30  return {month, day};
31  } else {
32  onDayOfMonth = -onDayOfMonth;
33  auto limitDate = LocalDate::forComponents(year, month, onDayOfMonth);
34  int8_t dayOfWeekShift = (limitDate.dayOfWeek() - onDayOfWeek + 7) % 7;
35  int8_t day = onDayOfMonth - dayOfWeekShift;
36  if (day < 1) {
37  // TODO: Support shifting from Jan to Dec of the previous year.
38  month--;
39  uint8_t daysInPrevMonth = LocalDate::daysInMonth(year, month);
40  day += daysInPrevMonth;
41  }
42  return {month, (uint8_t) day};
43  }
44 }
45 
46 } // internal
47 } // ace_time
ace_time::LocalDate::forComponents
static LocalDate forComponents(int16_t year, uint8_t month, uint8_t day)
Factory method using separated year, month and day fields.
Definition: LocalDate.h:106
ace_time::LocalDate::daysInMonth
static uint8_t daysInMonth(int16_t year, uint8_t month)
Return the number of days in the current month.
Definition: LocalDate.h:222