|
81 | 81 | */ |
82 | 82 |
|
83 | 83 | void RTClock::setTime (time_t time_stamp) { |
84 | | - rtc_set_count(time_stamp); |
| 84 | + breakTime(time_stamp, tmm); // time will be broken to tm |
| 85 | + setTime(tmm); |
| 86 | + //rtc_set_count(time_stamp); |
85 | 87 | } |
86 | 88 |
|
87 | | - void RTClock::setTime (struct tm* tm_ptr) { |
88 | | - rtc_set_count(mktime (tm_ptr)); |
89 | | - } |
| 89 | + #define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) ) |
90 | 90 |
|
| 91 | + //----------------------------------------------------------------------------- |
| 92 | +void RTClock::breakTime(time_t timeInput, tm_t & tmm) |
| 93 | +{ |
| 94 | +// break the given time_t into time components |
| 95 | +// this is a more compact version of the C library localtime function |
| 96 | +// note that year is offset from 1970 !!! |
| 97 | + |
| 98 | + uint8_t year; |
| 99 | + uint8_t month, monthLength; |
| 100 | + uint32_t time; |
| 101 | + uint32_t days; |
| 102 | + |
| 103 | + time = (uint32_t)timeInput; |
| 104 | + tmm.second = time % 60; |
| 105 | + time /= 60; // now it is minutes |
| 106 | + tmm.minute = time % 60; |
| 107 | + time /= 60; // now it is hours |
| 108 | + tmm.hour = time % 24; |
| 109 | + time /= 24; // now it is days |
| 110 | + tmm.weekday = ((time + 4) % 7); // Monday is day 1 // + 1; // Sunday is day 1 |
| 111 | + |
| 112 | + year = 0; |
| 113 | + days = 0; |
| 114 | + while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) { |
| 115 | + year++; |
| 116 | + } |
| 117 | + tmm.year = year; // year is offset from 1970 |
| 118 | + |
| 119 | + days -= LEAP_YEAR(year) ? 366 : 365; |
| 120 | + time -= days; // now it is days in this year, starting at 0 |
| 121 | + |
| 122 | + days = 0; |
| 123 | + month = 0; |
| 124 | + monthLength = 0; |
| 125 | + for (month=0; month<12; month++) { |
| 126 | + if (month==1) { // february |
| 127 | + if (LEAP_YEAR(year)) { |
| 128 | + monthLength=29; |
| 129 | + } else { |
| 130 | + monthLength=28; |
| 131 | + } |
| 132 | + } else { |
| 133 | + monthLength = monthDays[month]; |
| 134 | + } |
| 135 | + |
| 136 | + if (time >= monthLength) { |
| 137 | + time -= monthLength; |
| 138 | + } else { |
| 139 | + break; |
| 140 | + } |
| 141 | + } |
| 142 | + tmm.month = month + 1; // jan is month 1 |
| 143 | + tmm.day = time + 1; // day of month |
| 144 | +} |
| 145 | + |
| 146 | +//----------------------------------------------------------------------------- |
| 147 | +time_t RTClock::makeTime(tm_t & tmm) |
| 148 | +{ |
| 149 | +// assemble time elements into time_t |
| 150 | +// note year argument is offset from 1970 (see macros in time.h to convert to other formats) |
| 151 | +// previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9 |
| 152 | + |
| 153 | + int i; |
| 154 | + uint32_t seconds; |
| 155 | + |
| 156 | + // seconds from 1970 till 1 jan 00:00:00 of the given year |
| 157 | + seconds = tmm.year*(SECS_PER_DAY * 365); |
| 158 | + for (i = 0; i < tmm.year; i++) { |
| 159 | + if (LEAP_YEAR(i)) { |
| 160 | + seconds += SECS_PER_DAY; // add extra days for leap years |
| 161 | + } |
| 162 | + } |
| 163 | + |
| 164 | + // add days for this year, months start from 1 |
| 165 | + for (i = 1; i < tmm.month; i++) { |
| 166 | + if ( (i == 2) && LEAP_YEAR(tmm.year)) { |
| 167 | + seconds += SECS_PER_DAY * 29; |
| 168 | + } else { |
| 169 | + seconds += SECS_PER_DAY * monthDays[i-1]; //monthDay array starts from 0 |
| 170 | + } |
| 171 | + } |
| 172 | + seconds+= (tmm.day-1) * SECS_PER_DAY; |
| 173 | + seconds+= tmm.hour * SECS_PER_HOUR; |
| 174 | + seconds+= tmm.minute * SECS_PER_MIN; |
| 175 | + seconds+= tmm.second; |
| 176 | + return (time_t)seconds; |
| 177 | +} |
| 178 | + |
91 | 179 | time_t RTClock::getTime() { |
92 | 180 | return rtc_get_count(); |
93 | 181 | } |
94 | | - |
95 | | - struct tm* RTClock::getTime(struct tm* tm_ptr) { |
| 182 | + |
| 183 | + void RTClock::getTime(tm_t & tm_ptr) { |
96 | 184 | time_t res = rtc_get_count(); |
97 | | - tm_ptr = gmtime(&res); //why not gmtime? |
98 | | - return tm_ptr; |
| 185 | + breakTime(res, tm_ptr); |
99 | 186 | } |
100 | 187 |
|
101 | 188 | void RTClock::createAlarm(voidFuncPtr function, time_t alarm_time_t) { |
|
110 | 197 | rtc_detach_interrupt(RTC_SECONDS_INTERRUPT); |
111 | 198 | } |
112 | 199 |
|
113 | | - |
114 | | - void RTClock::createAlarm(voidFuncPtr function, tm* alarm_tm) { |
115 | | - time_t alarm = mktime(alarm_tm);//convert to time_t |
| 200 | + |
| 201 | + void RTClock::createAlarm(voidFuncPtr function, tm_t & alarm_tm) { |
| 202 | + time_t alarm = makeTime(alarm_tm);//convert to time_t |
116 | 203 | createAlarm(function, alarm); |
117 | 204 | } |
118 | 205 |
|
119 | 206 | //change alarm time |
120 | | - void RTClock::setAlarmTime (tm * tm_ptr) { |
121 | | - time_t time = mktime(tm_ptr);//convert to time_t |
| 207 | + |
| 208 | + void RTClock::setAlarmTime (tm_t & tm_ptr) { |
| 209 | + time_t time = makeTime(tm_ptr);//convert to time_t |
122 | 210 | rtc_set_alarm(time); //must be int... for standardization sake. |
123 | 211 | } |
124 | 212 |
|
|
0 commit comments