Simple time management w/o the Network interface
TimeInterface.cpp@1:b78c91e34eda, 2020-04-30 (annotated)
- Committer:
- WiredHome
- Date:
- Thu Apr 30 14:38:57 2020 +0000
- Revision:
- 1:b78c91e34eda
- Parent:
- 0:e8e62dfee5eb
Code cleanup
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
WiredHome | 0:e8e62dfee5eb | 1 | |
WiredHome | 0:e8e62dfee5eb | 2 | #include "TimeInterface.h" |
WiredHome | 0:e8e62dfee5eb | 3 | |
WiredHome | 0:e8e62dfee5eb | 4 | #include "rtc_api.h" |
WiredHome | 0:e8e62dfee5eb | 5 | |
WiredHome | 0:e8e62dfee5eb | 6 | //#define DEBUG "Time" |
WiredHome | 0:e8e62dfee5eb | 7 | #include <cstdio> |
WiredHome | 0:e8e62dfee5eb | 8 | #if (defined(DEBUG) && !defined(TARGET_LPC11U24)) |
WiredHome | 0:e8e62dfee5eb | 9 | #define DBG(x, ...) std::printf("[DBG %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); |
WiredHome | 0:e8e62dfee5eb | 10 | #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); |
WiredHome | 0:e8e62dfee5eb | 11 | #define ERR(x, ...) std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); |
WiredHome | 0:e8e62dfee5eb | 12 | #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); |
WiredHome | 0:e8e62dfee5eb | 13 | #else |
WiredHome | 0:e8e62dfee5eb | 14 | #define DBG(x, ...) |
WiredHome | 0:e8e62dfee5eb | 15 | #define WARN(x, ...) |
WiredHome | 0:e8e62dfee5eb | 16 | #define ERR(x, ...) |
WiredHome | 0:e8e62dfee5eb | 17 | #define INFO(x, ...) |
WiredHome | 0:e8e62dfee5eb | 18 | #endif |
WiredHome | 0:e8e62dfee5eb | 19 | |
WiredHome | 0:e8e62dfee5eb | 20 | #ifdef WIN32 |
WiredHome | 0:e8e62dfee5eb | 21 | // Fake it out for Win32 development and testing |
WiredHome | 0:e8e62dfee5eb | 22 | struct LPC { |
WiredHome | 0:e8e62dfee5eb | 23 | unsigned long CCR; // Clock Control register |
WiredHome | 0:e8e62dfee5eb | 24 | unsigned long GPREG0; // General Purpose Register #0 - 32-bit Battery backed |
WiredHome | 0:e8e62dfee5eb | 25 | unsigned long GPREG1; // General Purpose Register #1 - 32-bit Battery backed |
WiredHome | 0:e8e62dfee5eb | 26 | unsigned long CALIBRATION; // Calibration Register |
WiredHome | 0:e8e62dfee5eb | 27 | }; |
WiredHome | 0:e8e62dfee5eb | 28 | struct LPC X; |
WiredHome | 0:e8e62dfee5eb | 29 | struct LPC * LPC_RTC = &X; |
WiredHome | 0:e8e62dfee5eb | 30 | #define set_time(x) (void)x |
WiredHome | 0:e8e62dfee5eb | 31 | #endif |
WiredHome | 0:e8e62dfee5eb | 32 | |
WiredHome | 0:e8e62dfee5eb | 33 | |
WiredHome | 0:e8e62dfee5eb | 34 | TimeInterface::TimeInterface(void *net) |
WiredHome | 0:e8e62dfee5eb | 35 | { |
WiredHome | 0:e8e62dfee5eb | 36 | m_net = net; |
WiredHome | 0:e8e62dfee5eb | 37 | dst = false; |
WiredHome | 0:e8e62dfee5eb | 38 | memset(&dst_pair, 0, sizeof(dst_pair)); // that's enough to keep it from running |
WiredHome | 0:e8e62dfee5eb | 39 | } |
WiredHome | 0:e8e62dfee5eb | 40 | |
WiredHome | 0:e8e62dfee5eb | 41 | TimeInterface::~TimeInterface() |
WiredHome | 0:e8e62dfee5eb | 42 | { |
WiredHome | 0:e8e62dfee5eb | 43 | } |
WiredHome | 0:e8e62dfee5eb | 44 | |
WiredHome | 0:e8e62dfee5eb | 45 | #if 0 |
WiredHome | 0:e8e62dfee5eb | 46 | NTPResult TimeInterface::setTime(const char* host, uint16_t port, uint32_t timeout) |
WiredHome | 0:e8e62dfee5eb | 47 | { |
WiredHome | 0:e8e62dfee5eb | 48 | NTPResult res; |
WiredHome | 0:e8e62dfee5eb | 49 | |
WiredHome | 0:e8e62dfee5eb | 50 | if (m_net) { |
WiredHome | 0:e8e62dfee5eb | 51 | NTPClient ntp(m_net); |
WiredHome | 0:e8e62dfee5eb | 52 | // int16_t tzomin = get_tzo_min(); |
WiredHome | 0:e8e62dfee5eb | 53 | INFO("setTime(%s, %d, %d)\r\n", host, port, timeout); |
WiredHome | 0:e8e62dfee5eb | 54 | res = ntp.setTime(host, port, timeout); |
WiredHome | 0:e8e62dfee5eb | 55 | INFO(" ret: %d\r\n", res); |
WiredHome | 0:e8e62dfee5eb | 56 | if (res == NTP_OK) { |
WiredHome | 0:e8e62dfee5eb | 57 | // if the time was fetched successfully, then |
WiredHome | 0:e8e62dfee5eb | 58 | // let's save the time last set with the local tzo applied |
WiredHome | 0:e8e62dfee5eb | 59 | // and this saves the last time set for later precision |
WiredHome | 0:e8e62dfee5eb | 60 | // tuning. |
WiredHome | 0:e8e62dfee5eb | 61 | set_time(std::time(NULL)); |
WiredHome | 0:e8e62dfee5eb | 62 | } |
WiredHome | 0:e8e62dfee5eb | 63 | } else { |
WiredHome | 0:e8e62dfee5eb | 64 | ERR("No connection"); |
WiredHome | 0:e8e62dfee5eb | 65 | res = NTP_CONN; |
WiredHome | 0:e8e62dfee5eb | 66 | } |
WiredHome | 0:e8e62dfee5eb | 67 | return res; |
WiredHome | 0:e8e62dfee5eb | 68 | } |
WiredHome | 0:e8e62dfee5eb | 69 | #endif |
WiredHome | 0:e8e62dfee5eb | 70 | |
WiredHome | 0:e8e62dfee5eb | 71 | bool TimeInterface::parseDSTstring(TimeInterface::dst_event_t * result, const char * dstr) |
WiredHome | 0:e8e62dfee5eb | 72 | { |
WiredHome | 0:e8e62dfee5eb | 73 | int x; |
WiredHome | 0:e8e62dfee5eb | 74 | dst_event_t test_dst; |
WiredHome | 0:e8e62dfee5eb | 75 | |
WiredHome | 0:e8e62dfee5eb | 76 | x = atoi(dstr); |
WiredHome | 0:e8e62dfee5eb | 77 | if (x >= 1 && x <= 12) { |
WiredHome | 0:e8e62dfee5eb | 78 | test_dst.MM = x; |
WiredHome | 0:e8e62dfee5eb | 79 | dstr = strchr(dstr, '/'); |
WiredHome | 0:e8e62dfee5eb | 80 | if (dstr++) { |
WiredHome | 0:e8e62dfee5eb | 81 | x = atoi(dstr); |
WiredHome | 0:e8e62dfee5eb | 82 | if (x >= 1 && x <= 31) { |
WiredHome | 0:e8e62dfee5eb | 83 | test_dst.DD = x; |
WiredHome | 0:e8e62dfee5eb | 84 | dstr = strchr(dstr, ','); |
WiredHome | 0:e8e62dfee5eb | 85 | if (dstr++) { |
WiredHome | 0:e8e62dfee5eb | 86 | x = atoi(dstr); |
WiredHome | 0:e8e62dfee5eb | 87 | if (x >= 0 && x <= 23) { |
WiredHome | 0:e8e62dfee5eb | 88 | test_dst.hh = x; |
WiredHome | 0:e8e62dfee5eb | 89 | dstr = strchr(dstr, ':'); |
WiredHome | 0:e8e62dfee5eb | 90 | if (dstr++) { |
WiredHome | 0:e8e62dfee5eb | 91 | x = atoi(dstr); |
WiredHome | 0:e8e62dfee5eb | 92 | if (x >= 0 && x <= 59) { |
WiredHome | 0:e8e62dfee5eb | 93 | test_dst.mm = x; |
WiredHome | 0:e8e62dfee5eb | 94 | memcpy(result, &test_dst, sizeof(dst_event_t)); |
WiredHome | 0:e8e62dfee5eb | 95 | INFO("parsed: %d/%d %d:%02d", test_dst.MM, test_dst.DD, test_dst.hh, test_dst.mm); |
WiredHome | 0:e8e62dfee5eb | 96 | return true; |
WiredHome | 0:e8e62dfee5eb | 97 | } |
WiredHome | 0:e8e62dfee5eb | 98 | } |
WiredHome | 0:e8e62dfee5eb | 99 | } |
WiredHome | 0:e8e62dfee5eb | 100 | } |
WiredHome | 0:e8e62dfee5eb | 101 | } |
WiredHome | 0:e8e62dfee5eb | 102 | } |
WiredHome | 0:e8e62dfee5eb | 103 | } |
WiredHome | 0:e8e62dfee5eb | 104 | return false; |
WiredHome | 0:e8e62dfee5eb | 105 | } |
WiredHome | 0:e8e62dfee5eb | 106 | |
WiredHome | 0:e8e62dfee5eb | 107 | // parse MM/DD,hh:mm |
WiredHome | 0:e8e62dfee5eb | 108 | bool TimeInterface::set_dst(const char * dstStart, const char * dstStop) |
WiredHome | 0:e8e62dfee5eb | 109 | { |
WiredHome | 0:e8e62dfee5eb | 110 | dst_event_pair_t test_pair; |
WiredHome | 0:e8e62dfee5eb | 111 | |
WiredHome | 0:e8e62dfee5eb | 112 | if (parseDSTstring(&test_pair.dst_start, dstStart) |
WiredHome | 0:e8e62dfee5eb | 113 | && parseDSTstring(&test_pair.dst_stop, dstStop)) { |
WiredHome | 0:e8e62dfee5eb | 114 | memcpy(&dst_pair, &test_pair, sizeof(dst_event_pair_t)); |
WiredHome | 0:e8e62dfee5eb | 115 | INFO("set_dst from (%s,%s)", dstStart, dstStop); |
WiredHome | 0:e8e62dfee5eb | 116 | return true; |
WiredHome | 0:e8e62dfee5eb | 117 | } |
WiredHome | 0:e8e62dfee5eb | 118 | WARN("failed to set_dst from (%s,%s)", dstStart, dstStop); |
WiredHome | 0:e8e62dfee5eb | 119 | return false; |
WiredHome | 0:e8e62dfee5eb | 120 | } |
WiredHome | 0:e8e62dfee5eb | 121 | |
WiredHome | 0:e8e62dfee5eb | 122 | bool TimeInterface::set_dst(bool isdst) |
WiredHome | 0:e8e62dfee5eb | 123 | { |
WiredHome | 0:e8e62dfee5eb | 124 | dst = isdst; |
WiredHome | 0:e8e62dfee5eb | 125 | return true; |
WiredHome | 0:e8e62dfee5eb | 126 | } |
WiredHome | 0:e8e62dfee5eb | 127 | |
WiredHome | 0:e8e62dfee5eb | 128 | bool TimeInterface::get_dst(void) |
WiredHome | 0:e8e62dfee5eb | 129 | { |
WiredHome | 0:e8e62dfee5eb | 130 | return dst; |
WiredHome | 0:e8e62dfee5eb | 131 | } |
WiredHome | 0:e8e62dfee5eb | 132 | |
WiredHome | 0:e8e62dfee5eb | 133 | clock_t TimeInterface::clock(void) |
WiredHome | 0:e8e62dfee5eb | 134 | { |
WiredHome | 0:e8e62dfee5eb | 135 | return std::clock(); |
WiredHome | 0:e8e62dfee5eb | 136 | } |
WiredHome | 0:e8e62dfee5eb | 137 | |
WiredHome | 0:e8e62dfee5eb | 138 | time_t TimeInterface::time(time_t * timer) |
WiredHome | 0:e8e62dfee5eb | 139 | { |
WiredHome | 0:e8e62dfee5eb | 140 | return std::time(timer); |
WiredHome | 0:e8e62dfee5eb | 141 | } |
WiredHome | 0:e8e62dfee5eb | 142 | |
WiredHome | 0:e8e62dfee5eb | 143 | uint32_t TimeInterface::minutesSinceJan(int mon, int day, int hr, int min) |
WiredHome | 0:e8e62dfee5eb | 144 | { |
WiredHome | 0:e8e62dfee5eb | 145 | return (mon * 60 * 24 * 31) + (day * 60 * 24) + (hr * 60) + min; |
WiredHome | 0:e8e62dfee5eb | 146 | } |
WiredHome | 0:e8e62dfee5eb | 147 | |
WiredHome | 0:e8e62dfee5eb | 148 | time_t TimeInterface::timelocal(time_t * timer) |
WiredHome | 0:e8e62dfee5eb | 149 | { |
WiredHome | 0:e8e62dfee5eb | 150 | time_t privTime; |
WiredHome | 0:e8e62dfee5eb | 151 | struct tm * tminfo; |
WiredHome | 0:e8e62dfee5eb | 152 | |
WiredHome | 0:e8e62dfee5eb | 153 | if (dst_pair.dst_start.MM) { // may have to change the dst |
WiredHome | 0:e8e62dfee5eb | 154 | std::time(&privTime); |
WiredHome | 0:e8e62dfee5eb | 155 | tminfo = std::localtime(&privTime); |
WiredHome | 0:e8e62dfee5eb | 156 | |
WiredHome | 0:e8e62dfee5eb | 157 | uint32_t min_since_jan = minutesSinceJan(tminfo->tm_mon + 1, tminfo->tm_mday, tminfo->tm_hour, tminfo->tm_min); |
WiredHome | 0:e8e62dfee5eb | 158 | uint32_t min_dst_start = minutesSinceJan(dst_pair.dst_start.MM, dst_pair.dst_start.DD, dst_pair.dst_start.hh, dst_pair.dst_start.mm) + get_tzo_min(); |
WiredHome | 0:e8e62dfee5eb | 159 | uint32_t min_dst_stop = minutesSinceJan(dst_pair.dst_stop.MM, dst_pair.dst_stop.DD, dst_pair.dst_stop.hh, dst_pair.dst_stop.mm) + get_tzo_min(); |
WiredHome | 0:e8e62dfee5eb | 160 | |
WiredHome | 0:e8e62dfee5eb | 161 | if (min_since_jan >= min_dst_start && min_since_jan < min_dst_stop) { |
WiredHome | 0:e8e62dfee5eb | 162 | dst = 1; |
WiredHome | 0:e8e62dfee5eb | 163 | //INFO(" is dst: %u - %u - %u", min_since_jan, min_dst_start, min_dst_stop); |
WiredHome | 0:e8e62dfee5eb | 164 | } else { |
WiredHome | 0:e8e62dfee5eb | 165 | dst = 0; |
WiredHome | 0:e8e62dfee5eb | 166 | //INFO("not dst: %u - %u - %u", min_since_jan, min_dst_start, min_dst_stop); |
WiredHome | 0:e8e62dfee5eb | 167 | } |
WiredHome | 0:e8e62dfee5eb | 168 | } |
WiredHome | 0:e8e62dfee5eb | 169 | INFO(" timelocal: %u, %d, %d", std::time(timer), get_tzo_min(), dst); |
WiredHome | 0:e8e62dfee5eb | 170 | return std::time(timer) + get_tzo_min() * 60 + dst * 3600; |
WiredHome | 0:e8e62dfee5eb | 171 | } |
WiredHome | 0:e8e62dfee5eb | 172 | |
WiredHome | 0:e8e62dfee5eb | 173 | char * TimeInterface::ctime(const time_t * timer) |
WiredHome | 0:e8e62dfee5eb | 174 | { |
WiredHome | 0:e8e62dfee5eb | 175 | char * p = std::ctime(timer); |
WiredHome | 0:e8e62dfee5eb | 176 | |
WiredHome | 0:e8e62dfee5eb | 177 | if (strlen(p) < sizeof(result)) { |
WiredHome | 0:e8e62dfee5eb | 178 | strcpy(result, p); |
WiredHome | 0:e8e62dfee5eb | 179 | p = strchr(result, '\n'); |
WiredHome | 0:e8e62dfee5eb | 180 | if (p) |
WiredHome | 0:e8e62dfee5eb | 181 | *p = '\0'; |
WiredHome | 0:e8e62dfee5eb | 182 | } else { |
WiredHome | 0:e8e62dfee5eb | 183 | result[0] = '\0'; |
WiredHome | 0:e8e62dfee5eb | 184 | } |
WiredHome | 0:e8e62dfee5eb | 185 | return result; |
WiredHome | 0:e8e62dfee5eb | 186 | } |
WiredHome | 0:e8e62dfee5eb | 187 | |
WiredHome | 0:e8e62dfee5eb | 188 | char * TimeInterface::asctime(const struct tm_ex * timeptr) |
WiredHome | 0:e8e62dfee5eb | 189 | { |
WiredHome | 0:e8e62dfee5eb | 190 | static const char wday_name[][4] = { |
WiredHome | 0:e8e62dfee5eb | 191 | "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" |
WiredHome | 0:e8e62dfee5eb | 192 | }; |
WiredHome | 0:e8e62dfee5eb | 193 | static const char mon_name[][4] = { |
WiredHome | 0:e8e62dfee5eb | 194 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", |
WiredHome | 0:e8e62dfee5eb | 195 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" |
WiredHome | 0:e8e62dfee5eb | 196 | }; |
WiredHome | 0:e8e62dfee5eb | 197 | struct tm_ex tmp = *timeptr; |
WiredHome | 0:e8e62dfee5eb | 198 | |
WiredHome | 0:e8e62dfee5eb | 199 | tmp.tm_min += tmp.tm_tzo_min; |
WiredHome | 0:e8e62dfee5eb | 200 | if (tmp.tm_isdst) |
WiredHome | 0:e8e62dfee5eb | 201 | tmp.tm_min += 60; |
WiredHome | 0:e8e62dfee5eb | 202 | while (tmp.tm_min >= 60) { |
WiredHome | 0:e8e62dfee5eb | 203 | tmp.tm_min -= 60; |
WiredHome | 0:e8e62dfee5eb | 204 | tmp.tm_hour++; |
WiredHome | 0:e8e62dfee5eb | 205 | } |
WiredHome | 0:e8e62dfee5eb | 206 | while (tmp.tm_min < 0) { |
WiredHome | 0:e8e62dfee5eb | 207 | tmp.tm_min += 60; |
WiredHome | 0:e8e62dfee5eb | 208 | tmp.tm_hour--; |
WiredHome | 0:e8e62dfee5eb | 209 | } |
WiredHome | 0:e8e62dfee5eb | 210 | while (tmp.tm_hour >= 24) { |
WiredHome | 0:e8e62dfee5eb | 211 | tmp.tm_wday = (tmp.tm_wday + 1) % 7; |
WiredHome | 0:e8e62dfee5eb | 212 | tmp.tm_mday++; |
WiredHome | 0:e8e62dfee5eb | 213 | tmp.tm_hour -= 24; |
WiredHome | 0:e8e62dfee5eb | 214 | } |
WiredHome | 0:e8e62dfee5eb | 215 | while (tmp.tm_hour < 0) { |
WiredHome | 0:e8e62dfee5eb | 216 | tmp.tm_wday = (tmp.tm_wday + 6) % 7; |
WiredHome | 0:e8e62dfee5eb | 217 | tmp.tm_mday--; |
WiredHome | 0:e8e62dfee5eb | 218 | tmp.tm_hour += 24; |
WiredHome | 0:e8e62dfee5eb | 219 | } |
WiredHome | 0:e8e62dfee5eb | 220 | sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d", |
WiredHome | 0:e8e62dfee5eb | 221 | wday_name[tmp.tm_wday % 7], |
WiredHome | 0:e8e62dfee5eb | 222 | mon_name[tmp.tm_mon % 12], |
WiredHome | 1:b78c91e34eda | 223 | tmp.tm_mday % 99, tmp.tm_hour % 25, |
WiredHome | 1:b78c91e34eda | 224 | tmp.tm_min % 99, tmp.tm_sec % 99, |
WiredHome | 0:e8e62dfee5eb | 225 | 1900 + tmp.tm_year); |
WiredHome | 0:e8e62dfee5eb | 226 | return result; |
WiredHome | 0:e8e62dfee5eb | 227 | } |
WiredHome | 0:e8e62dfee5eb | 228 | |
WiredHome | 0:e8e62dfee5eb | 229 | struct tm_ex * TimeInterface::gmtime(const time_t * timer) |
WiredHome | 0:e8e62dfee5eb | 230 | { |
WiredHome | 0:e8e62dfee5eb | 231 | time_t priv = *timer + get_tzo_min() * 60 + dst * 3600; |
WiredHome | 0:e8e62dfee5eb | 232 | struct tm * tmp = std::localtime(&priv); |
WiredHome | 0:e8e62dfee5eb | 233 | |
WiredHome | 0:e8e62dfee5eb | 234 | tm_ext.tm_sec = tmp->tm_sec; |
WiredHome | 0:e8e62dfee5eb | 235 | tm_ext.tm_min = tmp->tm_min; |
WiredHome | 0:e8e62dfee5eb | 236 | tm_ext.tm_hour = tmp->tm_hour; |
WiredHome | 0:e8e62dfee5eb | 237 | tm_ext.tm_mday = tmp->tm_mday; |
WiredHome | 0:e8e62dfee5eb | 238 | tm_ext.tm_mon = tmp->tm_mon; |
WiredHome | 0:e8e62dfee5eb | 239 | tm_ext.tm_year = tmp->tm_year; |
WiredHome | 0:e8e62dfee5eb | 240 | tm_ext.tm_wday = tmp->tm_wday; |
WiredHome | 0:e8e62dfee5eb | 241 | tm_ext.tm_yday = tmp->tm_yday; |
WiredHome | 0:e8e62dfee5eb | 242 | tm_ext.tm_isdst = tmp->tm_isdst; |
WiredHome | 0:e8e62dfee5eb | 243 | tm_ext.tm_tzo_min = get_tzo_min(); |
WiredHome | 0:e8e62dfee5eb | 244 | return &tm_ext; |
WiredHome | 0:e8e62dfee5eb | 245 | } |
WiredHome | 0:e8e62dfee5eb | 246 | |
WiredHome | 0:e8e62dfee5eb | 247 | struct tm_ex * TimeInterface::localtime(const time_t * timer) |
WiredHome | 0:e8e62dfee5eb | 248 | { |
WiredHome | 0:e8e62dfee5eb | 249 | struct tm * tmp = std::localtime(timer); |
WiredHome | 0:e8e62dfee5eb | 250 | |
WiredHome | 0:e8e62dfee5eb | 251 | tm_ext.tm_sec = tmp->tm_sec; |
WiredHome | 0:e8e62dfee5eb | 252 | tm_ext.tm_min = tmp->tm_min; |
WiredHome | 0:e8e62dfee5eb | 253 | tm_ext.tm_hour = tmp->tm_hour; |
WiredHome | 0:e8e62dfee5eb | 254 | tm_ext.tm_mday = tmp->tm_mday; |
WiredHome | 0:e8e62dfee5eb | 255 | tm_ext.tm_mon = tmp->tm_mon; |
WiredHome | 0:e8e62dfee5eb | 256 | tm_ext.tm_year = tmp->tm_year; |
WiredHome | 0:e8e62dfee5eb | 257 | tm_ext.tm_wday = tmp->tm_wday; |
WiredHome | 0:e8e62dfee5eb | 258 | tm_ext.tm_yday = tmp->tm_yday; |
WiredHome | 0:e8e62dfee5eb | 259 | tm_ext.tm_isdst = tmp->tm_isdst; |
WiredHome | 0:e8e62dfee5eb | 260 | tm_ext.tm_tzo_min = get_tzo_min(); |
WiredHome | 0:e8e62dfee5eb | 261 | return &tm_ext; |
WiredHome | 0:e8e62dfee5eb | 262 | } |
WiredHome | 0:e8e62dfee5eb | 263 | |
WiredHome | 0:e8e62dfee5eb | 264 | time_t TimeInterface::mktime(struct tm_ex * timeptr) |
WiredHome | 0:e8e62dfee5eb | 265 | { |
WiredHome | 0:e8e62dfee5eb | 266 | timeptr->tm_tzo_min = get_tzo_min(); |
WiredHome | 0:e8e62dfee5eb | 267 | return std::mktime((struct tm *)timeptr); |
WiredHome | 0:e8e62dfee5eb | 268 | } |
WiredHome | 0:e8e62dfee5eb | 269 | |
WiredHome | 0:e8e62dfee5eb | 270 | size_t TimeInterface::strftime(char * ptr, size_t maxsize, const char * format, const struct tm_ex * timeptr) |
WiredHome | 0:e8e62dfee5eb | 271 | { |
WiredHome | 0:e8e62dfee5eb | 272 | return std::strftime(ptr, maxsize, format, (struct tm *)timeptr); |
WiredHome | 0:e8e62dfee5eb | 273 | } |
WiredHome | 0:e8e62dfee5eb | 274 | |
WiredHome | 0:e8e62dfee5eb | 275 | double TimeInterface::difftime(time_t end, time_t beginning) |
WiredHome | 0:e8e62dfee5eb | 276 | { |
WiredHome | 0:e8e62dfee5eb | 277 | return std::difftime(end, beginning); |
WiredHome | 0:e8e62dfee5eb | 278 | } |
WiredHome | 0:e8e62dfee5eb | 279 | |
WiredHome | 0:e8e62dfee5eb | 280 | |
WiredHome | 0:e8e62dfee5eb | 281 | |
WiredHome | 0:e8e62dfee5eb | 282 | // time zone functions |
WiredHome | 0:e8e62dfee5eb | 283 | |
WiredHome | 0:e8e62dfee5eb | 284 | void TimeInterface::set_time(time_t t, int16_t tzo_min) |
WiredHome | 0:e8e62dfee5eb | 285 | { |
WiredHome | 0:e8e62dfee5eb | 286 | time_t tval = t - (tzo_min * 60); |
WiredHome | 0:e8e62dfee5eb | 287 | rtc_init(); |
WiredHome | 0:e8e62dfee5eb | 288 | rtc_write(tval); |
WiredHome | 0:e8e62dfee5eb | 289 | LPC_RTC->GPREG1 = tval; |
WiredHome | 0:e8e62dfee5eb | 290 | INFO("set_time(%s)", ctime(&tval)); |
WiredHome | 0:e8e62dfee5eb | 291 | } |
WiredHome | 0:e8e62dfee5eb | 292 | |
WiredHome | 0:e8e62dfee5eb | 293 | void TimeInterface::set_tzo_min(int16_t tzo_min) |
WiredHome | 0:e8e62dfee5eb | 294 | { |
WiredHome | 0:e8e62dfee5eb | 295 | uint16_t th; |
WiredHome | 0:e8e62dfee5eb | 296 | uint32_t treg; |
WiredHome | 0:e8e62dfee5eb | 297 | |
WiredHome | 0:e8e62dfee5eb | 298 | if (tzo_min >= -720 && tzo_min <= 720) { |
WiredHome | 0:e8e62dfee5eb | 299 | th = (uint16_t)(-tzo_min); |
WiredHome | 0:e8e62dfee5eb | 300 | treg = (th << 16) | (uint16_t)tzo_min; |
WiredHome | 0:e8e62dfee5eb | 301 | LPC_RTC->GPREG0 = treg; |
WiredHome | 0:e8e62dfee5eb | 302 | //printf("set_tzo(%d) %d is %08X\r\n", tzo, th, LPC_RTC->GPREG0); |
WiredHome | 0:e8e62dfee5eb | 303 | } |
WiredHome | 0:e8e62dfee5eb | 304 | } |
WiredHome | 0:e8e62dfee5eb | 305 | |
WiredHome | 0:e8e62dfee5eb | 306 | int16_t TimeInterface::get_tzo_min(void) |
WiredHome | 0:e8e62dfee5eb | 307 | { |
WiredHome | 0:e8e62dfee5eb | 308 | uint16_t th, tl; |
WiredHome | 0:e8e62dfee5eb | 309 | |
WiredHome | 0:e8e62dfee5eb | 310 | th = LPC_RTC->GPREG0 >> 16; |
WiredHome | 0:e8e62dfee5eb | 311 | tl = LPC_RTC->GPREG0; |
WiredHome | 0:e8e62dfee5eb | 312 | //printf("get_tzo() is %04X %04X\r\n", th, tl); |
WiredHome | 0:e8e62dfee5eb | 313 | if ((uint16_t)(th + tl) == 0) { |
WiredHome | 0:e8e62dfee5eb | 314 | return tl; |
WiredHome | 0:e8e62dfee5eb | 315 | } else { |
WiredHome | 0:e8e62dfee5eb | 316 | return 0; |
WiredHome | 0:e8e62dfee5eb | 317 | } |
WiredHome | 0:e8e62dfee5eb | 318 | } |
WiredHome | 0:e8e62dfee5eb | 319 | |
WiredHome | 0:e8e62dfee5eb | 320 | time_t TimeInterface::get_timelastset(void) |
WiredHome | 0:e8e62dfee5eb | 321 | { |
WiredHome | 0:e8e62dfee5eb | 322 | return LPC_RTC->GPREG1; |
WiredHome | 0:e8e62dfee5eb | 323 | } |
WiredHome | 0:e8e62dfee5eb | 324 | |
WiredHome | 0:e8e62dfee5eb | 325 | int32_t TimeInterface::get_cal() |
WiredHome | 0:e8e62dfee5eb | 326 | { |
WiredHome | 0:e8e62dfee5eb | 327 | int32_t calvalue = LPC_RTC->CALIBRATION & 0x3FFFF; |
WiredHome | 0:e8e62dfee5eb | 328 | |
WiredHome | 0:e8e62dfee5eb | 329 | if (calvalue & 0x20000) { |
WiredHome | 0:e8e62dfee5eb | 330 | calvalue = -(calvalue & 0x1FFFF); |
WiredHome | 0:e8e62dfee5eb | 331 | } |
WiredHome | 0:e8e62dfee5eb | 332 | return calvalue; |
WiredHome | 0:e8e62dfee5eb | 333 | } |
WiredHome | 0:e8e62dfee5eb | 334 | |
WiredHome | 0:e8e62dfee5eb | 335 | void TimeInterface::set_cal(int32_t calibration) |
WiredHome | 0:e8e62dfee5eb | 336 | { |
WiredHome | 0:e8e62dfee5eb | 337 | if (calibration) { |
WiredHome | 0:e8e62dfee5eb | 338 | if (calibration < 0) { |
WiredHome | 0:e8e62dfee5eb | 339 | calibration = (-calibration & 0x1FFFF) | 0x20000; |
WiredHome | 0:e8e62dfee5eb | 340 | } |
WiredHome | 0:e8e62dfee5eb | 341 | LPC_RTC->CCR = 0x000001; //(LPC_RTC->CCR & 0x0003); // Clear CCALEN to enable it |
WiredHome | 0:e8e62dfee5eb | 342 | } else { |
WiredHome | 0:e8e62dfee5eb | 343 | LPC_RTC->CCR = 0x000011; //(LPC_RTC->CCR & 0x0003) | 0x0010; // Set CCALEN to disable it |
WiredHome | 0:e8e62dfee5eb | 344 | } |
WiredHome | 0:e8e62dfee5eb | 345 | LPC_RTC->CALIBRATION = calibration; |
WiredHome | 0:e8e62dfee5eb | 346 | } |
WiredHome | 0:e8e62dfee5eb | 347 | |
WiredHome | 0:e8e62dfee5eb | 348 | bool TimeInterface::adjust_sec(int32_t adjustSeconds) |
WiredHome | 0:e8e62dfee5eb | 349 | { |
WiredHome | 0:e8e62dfee5eb | 350 | time_t lastSet = get_timelastset(); |
WiredHome | 0:e8e62dfee5eb | 351 | |
WiredHome | 0:e8e62dfee5eb | 352 | if (lastSet != 0) { |
WiredHome | 0:e8e62dfee5eb | 353 | time_t seconds = time(NULL); // get "now" according to the rtc |
WiredHome | 0:e8e62dfee5eb | 354 | int32_t delta = seconds - lastSet; |
WiredHome | 0:e8e62dfee5eb | 355 | //int32_t curCal = get_cal(); // calibration might want to leverage the current cal factor. |
WiredHome | 0:e8e62dfee5eb | 356 | int32_t calMAX = 131071; |
WiredHome | 0:e8e62dfee5eb | 357 | int32_t secPerDay = 86400; |
WiredHome | 0:e8e62dfee5eb | 358 | float errSecPerDay; |
WiredHome | 0:e8e62dfee5eb | 359 | |
WiredHome | 0:e8e62dfee5eb | 360 | // Convert the current calibration and the adjustment into |
WiredHome | 0:e8e62dfee5eb | 361 | // the new calibration value |
WiredHome | 0:e8e62dfee5eb | 362 | // assume it is +10sec and it has been 2days, then the adjustment |
WiredHome | 0:e8e62dfee5eb | 363 | // needs to be +5 sec per day, or one adjustment every 1/5th |
WiredHome | 0:e8e62dfee5eb | 364 | // of a day, or 1 adjustment every 86400/5 counts. |
WiredHome | 0:e8e62dfee5eb | 365 | // delta = now - then (number of elapsed seconds) |
WiredHome | 0:e8e62dfee5eb | 366 | if (adjustSeconds != 0 && delta != 0) { |
WiredHome | 0:e8e62dfee5eb | 367 | int32_t calFactor; |
WiredHome | 0:e8e62dfee5eb | 368 | |
WiredHome | 0:e8e62dfee5eb | 369 | // Make the clock correct |
WiredHome | 0:e8e62dfee5eb | 370 | seconds = seconds + adjustSeconds; |
WiredHome | 0:e8e62dfee5eb | 371 | set_time(seconds); |
WiredHome | 0:e8e62dfee5eb | 372 | // Compute the calibration factor |
WiredHome | 0:e8e62dfee5eb | 373 | errSecPerDay = (float)adjustSeconds / ((float)(delta)/secPerDay); |
WiredHome | 0:e8e62dfee5eb | 374 | calFactor = (int32_t)((float)secPerDay/errSecPerDay); |
WiredHome | 0:e8e62dfee5eb | 375 | if (abs(calFactor) < calMAX) |
WiredHome | 0:e8e62dfee5eb | 376 | set_cal(calFactor); |
WiredHome | 0:e8e62dfee5eb | 377 | } |
WiredHome | 0:e8e62dfee5eb | 378 | return true; |
WiredHome | 0:e8e62dfee5eb | 379 | } else { |
WiredHome | 0:e8e62dfee5eb | 380 | return false; |
WiredHome | 0:e8e62dfee5eb | 381 | } |
WiredHome | 0:e8e62dfee5eb | 382 | } |
WiredHome | 0:e8e62dfee5eb | 383 | |
WiredHome | 0:e8e62dfee5eb | 384 | |
WiredHome | 0:e8e62dfee5eb | 385 | // ############################################################################# |
WiredHome | 0:e8e62dfee5eb | 386 | /* |
WiredHome | 0:e8e62dfee5eb | 387 | * Enhancement to use a custom tm_ex struct and the time zone by D. Smart |
WiredHome | 0:e8e62dfee5eb | 388 | * %Z |
WiredHome | 0:e8e62dfee5eb | 389 | * |
WiredHome | 0:e8e62dfee5eb | 390 | * Copyright (c) 1994 Powerdog Industries. All rights reserved. |
WiredHome | 0:e8e62dfee5eb | 391 | * |
WiredHome | 0:e8e62dfee5eb | 392 | * Redistribution and use in source and binary forms, without |
WiredHome | 0:e8e62dfee5eb | 393 | * modification, are permitted provided that the following conditions |
WiredHome | 0:e8e62dfee5eb | 394 | * are met: |
WiredHome | 0:e8e62dfee5eb | 395 | * 1. Redistributions of source code must retain the above copyright |
WiredHome | 0:e8e62dfee5eb | 396 | * notice, this list of conditions and the following disclaimer. |
WiredHome | 0:e8e62dfee5eb | 397 | * 2. Redistributions in binary form must reproduce the above copyright |
WiredHome | 0:e8e62dfee5eb | 398 | * notice, this list of conditions and the following disclaimer |
WiredHome | 0:e8e62dfee5eb | 399 | * in the documentation and/or other materials provided with the |
WiredHome | 0:e8e62dfee5eb | 400 | * distribution. |
WiredHome | 0:e8e62dfee5eb | 401 | * 3. All advertising materials mentioning features or use of this |
WiredHome | 0:e8e62dfee5eb | 402 | * software must display the following acknowledgement: |
WiredHome | 0:e8e62dfee5eb | 403 | * This product includes software developed by Powerdog Industries. |
WiredHome | 0:e8e62dfee5eb | 404 | * 4. The name of Powerdog Industries may not be used to endorse or |
WiredHome | 0:e8e62dfee5eb | 405 | * promote products derived from this software without specific prior |
WiredHome | 0:e8e62dfee5eb | 406 | * written permission. |
WiredHome | 0:e8e62dfee5eb | 407 | * |
WiredHome | 0:e8e62dfee5eb | 408 | * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``AS IS'' AND ANY |
WiredHome | 0:e8e62dfee5eb | 409 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
WiredHome | 0:e8e62dfee5eb | 410 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
WiredHome | 0:e8e62dfee5eb | 411 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE POWERDOG INDUSTRIES BE |
WiredHome | 0:e8e62dfee5eb | 412 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
WiredHome | 0:e8e62dfee5eb | 413 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
WiredHome | 0:e8e62dfee5eb | 414 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
WiredHome | 0:e8e62dfee5eb | 415 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
WiredHome | 0:e8e62dfee5eb | 416 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
WiredHome | 0:e8e62dfee5eb | 417 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
WiredHome | 0:e8e62dfee5eb | 418 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
WiredHome | 0:e8e62dfee5eb | 419 | */ |
WiredHome | 0:e8e62dfee5eb | 420 | |
WiredHome | 0:e8e62dfee5eb | 421 | #define asizeof(a) (sizeof (a) / sizeof ((a)[0])) |
WiredHome | 0:e8e62dfee5eb | 422 | |
WiredHome | 0:e8e62dfee5eb | 423 | struct dtconv { |
WiredHome | 1:b78c91e34eda | 424 | const char *abbrev_month_names[12]; |
WiredHome | 1:b78c91e34eda | 425 | const char *month_names[12]; |
WiredHome | 1:b78c91e34eda | 426 | const char *abbrev_weekday_names[7]; |
WiredHome | 1:b78c91e34eda | 427 | const char *weekday_names[7]; |
WiredHome | 1:b78c91e34eda | 428 | const char *time_format; |
WiredHome | 1:b78c91e34eda | 429 | const char *sdate_format; |
WiredHome | 1:b78c91e34eda | 430 | const char *dtime_format; |
WiredHome | 1:b78c91e34eda | 431 | const char *am_string; |
WiredHome | 1:b78c91e34eda | 432 | const char *pm_string; |
WiredHome | 1:b78c91e34eda | 433 | const char *ldate_format; |
WiredHome | 1:b78c91e34eda | 434 | const char *zone_names[10]; |
WiredHome | 0:e8e62dfee5eb | 435 | int8_t zone_offsets[10]; |
WiredHome | 0:e8e62dfee5eb | 436 | }; |
WiredHome | 0:e8e62dfee5eb | 437 | |
WiredHome | 0:e8e62dfee5eb | 438 | static const struct dtconv En_US = { |
WiredHome | 0:e8e62dfee5eb | 439 | { |
WiredHome | 0:e8e62dfee5eb | 440 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", |
WiredHome | 0:e8e62dfee5eb | 441 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" |
WiredHome | 0:e8e62dfee5eb | 442 | }, |
WiredHome | 0:e8e62dfee5eb | 443 | { |
WiredHome | 0:e8e62dfee5eb | 444 | "January", "February", "March", "April", |
WiredHome | 0:e8e62dfee5eb | 445 | "May", "June", "July", "August", |
WiredHome | 0:e8e62dfee5eb | 446 | "September", "October", "November", "December" |
WiredHome | 0:e8e62dfee5eb | 447 | }, |
WiredHome | 0:e8e62dfee5eb | 448 | { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }, |
WiredHome | 0:e8e62dfee5eb | 449 | { |
WiredHome | 0:e8e62dfee5eb | 450 | "Sunday", "Monday", "Tuesday", "Wednesday", |
WiredHome | 0:e8e62dfee5eb | 451 | "Thursday", "Friday", "Saturday" |
WiredHome | 0:e8e62dfee5eb | 452 | }, |
WiredHome | 0:e8e62dfee5eb | 453 | "%H:%M:%S", |
WiredHome | 0:e8e62dfee5eb | 454 | "%m/%d/%y", |
WiredHome | 0:e8e62dfee5eb | 455 | "%a %b %e %T %Z %Y", |
WiredHome | 0:e8e62dfee5eb | 456 | "AM", |
WiredHome | 0:e8e62dfee5eb | 457 | "PM", |
WiredHome | 0:e8e62dfee5eb | 458 | "%A, %B, %e, %Y", |
WiredHome | 0:e8e62dfee5eb | 459 | { "UTC", "EST", "CST", "MST", "PST", "YST", "CAT", "HST", "CET", "EET", }, |
WiredHome | 0:e8e62dfee5eb | 460 | { 0, -5, -6, -7, -8, -9, -10, -10, +1, +2, }, |
WiredHome | 0:e8e62dfee5eb | 461 | }; |
WiredHome | 0:e8e62dfee5eb | 462 | |
WiredHome | 0:e8e62dfee5eb | 463 | |
WiredHome | 0:e8e62dfee5eb | 464 | #ifndef isprint |
WiredHome | 0:e8e62dfee5eb | 465 | #define in_range(c, lo, up) ((uint8_t)c >= lo && (uint8_t)c <= up) |
WiredHome | 0:e8e62dfee5eb | 466 | #define isprint(c) in_range(c, 0x20, 0x7f) |
WiredHome | 0:e8e62dfee5eb | 467 | #define isdigit(c) in_range(c, '0', '9') |
WiredHome | 0:e8e62dfee5eb | 468 | #define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) |
WiredHome | 0:e8e62dfee5eb | 469 | #define islower(c) in_range(c, 'a', 'z') |
WiredHome | 0:e8e62dfee5eb | 470 | #define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') |
WiredHome | 0:e8e62dfee5eb | 471 | #endif |
WiredHome | 0:e8e62dfee5eb | 472 | |
WiredHome | 0:e8e62dfee5eb | 473 | |
WiredHome | 1:b78c91e34eda | 474 | const char * TimeInterface::strptime(const char *buf, const char *fmt, struct tm_ex *tm) |
WiredHome | 0:e8e62dfee5eb | 475 | { |
WiredHome | 1:b78c91e34eda | 476 | char c; |
WiredHome | 1:b78c91e34eda | 477 | const char *ptr; |
WiredHome | 0:e8e62dfee5eb | 478 | int i, len; |
WiredHome | 1:b78c91e34eda | 479 | size_t ndx; |
WiredHome | 0:e8e62dfee5eb | 480 | bool fSet_wday = false; // so we can notice if the wday was set |
WiredHome | 0:e8e62dfee5eb | 481 | |
WiredHome | 0:e8e62dfee5eb | 482 | ptr = fmt; |
WiredHome | 0:e8e62dfee5eb | 483 | while (*ptr != 0) { |
WiredHome | 0:e8e62dfee5eb | 484 | if (*buf == 0) |
WiredHome | 0:e8e62dfee5eb | 485 | break; |
WiredHome | 0:e8e62dfee5eb | 486 | |
WiredHome | 0:e8e62dfee5eb | 487 | c = *ptr++; |
WiredHome | 0:e8e62dfee5eb | 488 | |
WiredHome | 0:e8e62dfee5eb | 489 | if (c != '%') { |
WiredHome | 0:e8e62dfee5eb | 490 | if (isspace(c)) |
WiredHome | 0:e8e62dfee5eb | 491 | while (*buf != 0 && isspace(*buf)) |
WiredHome | 0:e8e62dfee5eb | 492 | buf++; |
WiredHome | 0:e8e62dfee5eb | 493 | else if (c != *buf++) |
WiredHome | 0:e8e62dfee5eb | 494 | return 0; |
WiredHome | 0:e8e62dfee5eb | 495 | continue; |
WiredHome | 0:e8e62dfee5eb | 496 | } |
WiredHome | 0:e8e62dfee5eb | 497 | |
WiredHome | 0:e8e62dfee5eb | 498 | c = *ptr++; |
WiredHome | 0:e8e62dfee5eb | 499 | switch (c) { |
WiredHome | 0:e8e62dfee5eb | 500 | case 0: |
WiredHome | 0:e8e62dfee5eb | 501 | case '%': |
WiredHome | 0:e8e62dfee5eb | 502 | if (*buf++ != '%') |
WiredHome | 0:e8e62dfee5eb | 503 | return 0; |
WiredHome | 0:e8e62dfee5eb | 504 | break; |
WiredHome | 0:e8e62dfee5eb | 505 | |
WiredHome | 0:e8e62dfee5eb | 506 | case 'C': |
WiredHome | 0:e8e62dfee5eb | 507 | buf = strptime(buf, En_US.ldate_format, tm); |
WiredHome | 0:e8e62dfee5eb | 508 | if (buf == 0) |
WiredHome | 0:e8e62dfee5eb | 509 | return 0; |
WiredHome | 0:e8e62dfee5eb | 510 | break; |
WiredHome | 0:e8e62dfee5eb | 511 | |
WiredHome | 0:e8e62dfee5eb | 512 | case 'c': |
WiredHome | 0:e8e62dfee5eb | 513 | buf = strptime(buf, "%x %X", tm); |
WiredHome | 0:e8e62dfee5eb | 514 | if (buf == 0) |
WiredHome | 0:e8e62dfee5eb | 515 | return 0; |
WiredHome | 0:e8e62dfee5eb | 516 | break; |
WiredHome | 0:e8e62dfee5eb | 517 | |
WiredHome | 0:e8e62dfee5eb | 518 | case 'D': |
WiredHome | 0:e8e62dfee5eb | 519 | buf = strptime(buf, "%m/%d/%y", tm); |
WiredHome | 0:e8e62dfee5eb | 520 | if (buf == 0) |
WiredHome | 0:e8e62dfee5eb | 521 | return 0; |
WiredHome | 0:e8e62dfee5eb | 522 | break; |
WiredHome | 0:e8e62dfee5eb | 523 | |
WiredHome | 0:e8e62dfee5eb | 524 | case 'R': |
WiredHome | 0:e8e62dfee5eb | 525 | buf = strptime(buf, "%H:%M", tm); |
WiredHome | 0:e8e62dfee5eb | 526 | if (buf == 0) |
WiredHome | 0:e8e62dfee5eb | 527 | return 0; |
WiredHome | 0:e8e62dfee5eb | 528 | break; |
WiredHome | 0:e8e62dfee5eb | 529 | |
WiredHome | 0:e8e62dfee5eb | 530 | case 'r': |
WiredHome | 0:e8e62dfee5eb | 531 | buf = strptime(buf, "%I:%M:%S %p", tm); |
WiredHome | 0:e8e62dfee5eb | 532 | if (buf == 0) |
WiredHome | 0:e8e62dfee5eb | 533 | return 0; |
WiredHome | 0:e8e62dfee5eb | 534 | break; |
WiredHome | 0:e8e62dfee5eb | 535 | |
WiredHome | 0:e8e62dfee5eb | 536 | case 'T': |
WiredHome | 0:e8e62dfee5eb | 537 | buf = strptime(buf, "%H:%M:%S", tm); |
WiredHome | 0:e8e62dfee5eb | 538 | if (buf == 0) |
WiredHome | 0:e8e62dfee5eb | 539 | return 0; |
WiredHome | 0:e8e62dfee5eb | 540 | break; |
WiredHome | 0:e8e62dfee5eb | 541 | |
WiredHome | 0:e8e62dfee5eb | 542 | case 'X': |
WiredHome | 0:e8e62dfee5eb | 543 | buf = strptime(buf, En_US.time_format, tm); |
WiredHome | 0:e8e62dfee5eb | 544 | if (buf == 0) |
WiredHome | 0:e8e62dfee5eb | 545 | return 0; |
WiredHome | 0:e8e62dfee5eb | 546 | break; |
WiredHome | 0:e8e62dfee5eb | 547 | |
WiredHome | 0:e8e62dfee5eb | 548 | case 'x': |
WiredHome | 0:e8e62dfee5eb | 549 | buf = strptime(buf, En_US.sdate_format, tm); |
WiredHome | 0:e8e62dfee5eb | 550 | if (buf == 0) |
WiredHome | 0:e8e62dfee5eb | 551 | return 0; |
WiredHome | 0:e8e62dfee5eb | 552 | break; |
WiredHome | 0:e8e62dfee5eb | 553 | |
WiredHome | 0:e8e62dfee5eb | 554 | case 'j': |
WiredHome | 0:e8e62dfee5eb | 555 | if (!isdigit(*buf)) |
WiredHome | 0:e8e62dfee5eb | 556 | return 0; |
WiredHome | 0:e8e62dfee5eb | 557 | |
WiredHome | 0:e8e62dfee5eb | 558 | for (i = 0; *buf != 0 && isdigit(*buf); buf++) { |
WiredHome | 0:e8e62dfee5eb | 559 | i *= 10; |
WiredHome | 0:e8e62dfee5eb | 560 | i += *buf - '0'; |
WiredHome | 0:e8e62dfee5eb | 561 | } |
WiredHome | 0:e8e62dfee5eb | 562 | if (i > 365) |
WiredHome | 0:e8e62dfee5eb | 563 | return 0; |
WiredHome | 0:e8e62dfee5eb | 564 | |
WiredHome | 0:e8e62dfee5eb | 565 | tm->tm_yday = i; |
WiredHome | 0:e8e62dfee5eb | 566 | break; |
WiredHome | 0:e8e62dfee5eb | 567 | |
WiredHome | 0:e8e62dfee5eb | 568 | case 'M': |
WiredHome | 0:e8e62dfee5eb | 569 | case 'S': |
WiredHome | 0:e8e62dfee5eb | 570 | if (*buf == 0 || isspace(*buf)) |
WiredHome | 0:e8e62dfee5eb | 571 | break; |
WiredHome | 0:e8e62dfee5eb | 572 | |
WiredHome | 0:e8e62dfee5eb | 573 | if (!isdigit(*buf)) |
WiredHome | 0:e8e62dfee5eb | 574 | return 0; |
WiredHome | 0:e8e62dfee5eb | 575 | |
WiredHome | 0:e8e62dfee5eb | 576 | for (i = 0; *buf != 0 && isdigit(*buf); buf++) { |
WiredHome | 0:e8e62dfee5eb | 577 | i *= 10; |
WiredHome | 0:e8e62dfee5eb | 578 | i += *buf - '0'; |
WiredHome | 0:e8e62dfee5eb | 579 | } |
WiredHome | 0:e8e62dfee5eb | 580 | if (i > 59) |
WiredHome | 0:e8e62dfee5eb | 581 | return 0; |
WiredHome | 0:e8e62dfee5eb | 582 | |
WiredHome | 0:e8e62dfee5eb | 583 | if (c == 'M') |
WiredHome | 0:e8e62dfee5eb | 584 | tm->tm_min = i; |
WiredHome | 0:e8e62dfee5eb | 585 | else |
WiredHome | 0:e8e62dfee5eb | 586 | tm->tm_sec = i; |
WiredHome | 0:e8e62dfee5eb | 587 | |
WiredHome | 0:e8e62dfee5eb | 588 | if (*buf != 0 && isspace(*buf)) |
WiredHome | 0:e8e62dfee5eb | 589 | while (*ptr != 0 && !isspace(*ptr)) |
WiredHome | 0:e8e62dfee5eb | 590 | ptr++; |
WiredHome | 0:e8e62dfee5eb | 591 | break; |
WiredHome | 0:e8e62dfee5eb | 592 | |
WiredHome | 0:e8e62dfee5eb | 593 | case 'H': |
WiredHome | 0:e8e62dfee5eb | 594 | case 'I': |
WiredHome | 0:e8e62dfee5eb | 595 | case 'k': |
WiredHome | 0:e8e62dfee5eb | 596 | case 'l': |
WiredHome | 0:e8e62dfee5eb | 597 | if (!isdigit(*buf)) |
WiredHome | 0:e8e62dfee5eb | 598 | return 0; |
WiredHome | 0:e8e62dfee5eb | 599 | |
WiredHome | 0:e8e62dfee5eb | 600 | for (i = 0; *buf != 0 && isdigit(*buf); buf++) { |
WiredHome | 0:e8e62dfee5eb | 601 | i *= 10; |
WiredHome | 0:e8e62dfee5eb | 602 | i += *buf - '0'; |
WiredHome | 0:e8e62dfee5eb | 603 | } |
WiredHome | 0:e8e62dfee5eb | 604 | if (c == 'H' || c == 'k') { |
WiredHome | 0:e8e62dfee5eb | 605 | if (i > 23) |
WiredHome | 0:e8e62dfee5eb | 606 | return 0; |
WiredHome | 0:e8e62dfee5eb | 607 | } else if (i > 11) |
WiredHome | 0:e8e62dfee5eb | 608 | return 0; |
WiredHome | 0:e8e62dfee5eb | 609 | |
WiredHome | 0:e8e62dfee5eb | 610 | tm->tm_hour = i; |
WiredHome | 0:e8e62dfee5eb | 611 | |
WiredHome | 0:e8e62dfee5eb | 612 | if (*buf != 0 && isspace(*buf)) |
WiredHome | 0:e8e62dfee5eb | 613 | while (*ptr != 0 && !isspace(*ptr)) |
WiredHome | 0:e8e62dfee5eb | 614 | ptr++; |
WiredHome | 0:e8e62dfee5eb | 615 | break; |
WiredHome | 0:e8e62dfee5eb | 616 | |
WiredHome | 0:e8e62dfee5eb | 617 | case 'p': |
WiredHome | 0:e8e62dfee5eb | 618 | len = strlen(En_US.am_string); |
WiredHome | 0:e8e62dfee5eb | 619 | if (strncasecmp(buf, En_US.am_string, len) == 0) { |
WiredHome | 0:e8e62dfee5eb | 620 | if (tm->tm_hour > 12) |
WiredHome | 0:e8e62dfee5eb | 621 | return 0; |
WiredHome | 0:e8e62dfee5eb | 622 | if (tm->tm_hour == 12) |
WiredHome | 0:e8e62dfee5eb | 623 | tm->tm_hour = 0; |
WiredHome | 0:e8e62dfee5eb | 624 | buf += len; |
WiredHome | 0:e8e62dfee5eb | 625 | break; |
WiredHome | 0:e8e62dfee5eb | 626 | } |
WiredHome | 0:e8e62dfee5eb | 627 | |
WiredHome | 0:e8e62dfee5eb | 628 | len = strlen(En_US.pm_string); |
WiredHome | 0:e8e62dfee5eb | 629 | if (strncasecmp(buf, En_US.pm_string, len) == 0) { |
WiredHome | 0:e8e62dfee5eb | 630 | if (tm->tm_hour > 12) |
WiredHome | 0:e8e62dfee5eb | 631 | return 0; |
WiredHome | 0:e8e62dfee5eb | 632 | if (tm->tm_hour != 12) |
WiredHome | 0:e8e62dfee5eb | 633 | tm->tm_hour += 12; |
WiredHome | 0:e8e62dfee5eb | 634 | buf += len; |
WiredHome | 0:e8e62dfee5eb | 635 | break; |
WiredHome | 0:e8e62dfee5eb | 636 | } |
WiredHome | 0:e8e62dfee5eb | 637 | |
WiredHome | 0:e8e62dfee5eb | 638 | return 0; |
WiredHome | 0:e8e62dfee5eb | 639 | |
WiredHome | 0:e8e62dfee5eb | 640 | case 'A': |
WiredHome | 0:e8e62dfee5eb | 641 | case 'a': |
WiredHome | 1:b78c91e34eda | 642 | for (ndx = 0; ndx < asizeof(En_US.weekday_names); ndx++) { |
WiredHome | 1:b78c91e34eda | 643 | len = strlen(En_US.weekday_names[ndx]); |
WiredHome | 1:b78c91e34eda | 644 | if (strncasecmp(buf, En_US.weekday_names[ndx], len) == 0) |
WiredHome | 0:e8e62dfee5eb | 645 | break; |
WiredHome | 0:e8e62dfee5eb | 646 | |
WiredHome | 1:b78c91e34eda | 647 | len = strlen(En_US.abbrev_weekday_names[ndx]); |
WiredHome | 1:b78c91e34eda | 648 | if (strncasecmp(buf, En_US.abbrev_weekday_names[ndx], len) == 0) |
WiredHome | 0:e8e62dfee5eb | 649 | break; |
WiredHome | 0:e8e62dfee5eb | 650 | } |
WiredHome | 1:b78c91e34eda | 651 | if (ndx == asizeof(En_US.weekday_names)) |
WiredHome | 0:e8e62dfee5eb | 652 | return 0; |
WiredHome | 0:e8e62dfee5eb | 653 | fSet_wday = true; |
WiredHome | 1:b78c91e34eda | 654 | tm->tm_wday = ndx; |
WiredHome | 0:e8e62dfee5eb | 655 | buf += len; |
WiredHome | 0:e8e62dfee5eb | 656 | break; |
WiredHome | 0:e8e62dfee5eb | 657 | |
WiredHome | 0:e8e62dfee5eb | 658 | case 'd': |
WiredHome | 0:e8e62dfee5eb | 659 | case 'e': |
WiredHome | 0:e8e62dfee5eb | 660 | if (!isdigit(*buf)) |
WiredHome | 0:e8e62dfee5eb | 661 | return 0; |
WiredHome | 0:e8e62dfee5eb | 662 | |
WiredHome | 0:e8e62dfee5eb | 663 | for (i = 0; *buf != 0 && isdigit(*buf); buf++) { |
WiredHome | 0:e8e62dfee5eb | 664 | i *= 10; |
WiredHome | 0:e8e62dfee5eb | 665 | i += *buf - '0'; |
WiredHome | 0:e8e62dfee5eb | 666 | } |
WiredHome | 0:e8e62dfee5eb | 667 | if (i > 31) |
WiredHome | 0:e8e62dfee5eb | 668 | return 0; |
WiredHome | 0:e8e62dfee5eb | 669 | |
WiredHome | 0:e8e62dfee5eb | 670 | tm->tm_mday = i; |
WiredHome | 0:e8e62dfee5eb | 671 | |
WiredHome | 0:e8e62dfee5eb | 672 | if (*buf != 0 && isspace(*buf)) |
WiredHome | 0:e8e62dfee5eb | 673 | while (*ptr != 0 && !isspace(*ptr)) |
WiredHome | 0:e8e62dfee5eb | 674 | ptr++; |
WiredHome | 0:e8e62dfee5eb | 675 | break; |
WiredHome | 0:e8e62dfee5eb | 676 | |
WiredHome | 0:e8e62dfee5eb | 677 | case 'B': |
WiredHome | 0:e8e62dfee5eb | 678 | case 'b': |
WiredHome | 0:e8e62dfee5eb | 679 | case 'h': |
WiredHome | 1:b78c91e34eda | 680 | for (ndx = 0; ndx < asizeof(En_US.month_names); ndx++) { |
WiredHome | 1:b78c91e34eda | 681 | len = strlen(En_US.month_names[ndx]); |
WiredHome | 1:b78c91e34eda | 682 | if (strncasecmp(buf, En_US.month_names[ndx], len) == 0) |
WiredHome | 0:e8e62dfee5eb | 683 | break; |
WiredHome | 0:e8e62dfee5eb | 684 | |
WiredHome | 1:b78c91e34eda | 685 | len = strlen(En_US.abbrev_month_names[ndx]); |
WiredHome | 1:b78c91e34eda | 686 | if (strncasecmp(buf, En_US.abbrev_month_names[ndx], len) == 0) |
WiredHome | 0:e8e62dfee5eb | 687 | break; |
WiredHome | 0:e8e62dfee5eb | 688 | } |
WiredHome | 1:b78c91e34eda | 689 | if (ndx == asizeof(En_US.month_names)) |
WiredHome | 0:e8e62dfee5eb | 690 | return 0; |
WiredHome | 0:e8e62dfee5eb | 691 | |
WiredHome | 1:b78c91e34eda | 692 | tm->tm_mon = ndx; |
WiredHome | 0:e8e62dfee5eb | 693 | buf += len; |
WiredHome | 0:e8e62dfee5eb | 694 | break; |
WiredHome | 0:e8e62dfee5eb | 695 | |
WiredHome | 0:e8e62dfee5eb | 696 | case 'm': |
WiredHome | 0:e8e62dfee5eb | 697 | if (!isdigit(*buf)) |
WiredHome | 0:e8e62dfee5eb | 698 | return 0; |
WiredHome | 0:e8e62dfee5eb | 699 | |
WiredHome | 0:e8e62dfee5eb | 700 | for (i = 0; *buf != 0 && isdigit(*buf); buf++) { |
WiredHome | 0:e8e62dfee5eb | 701 | i *= 10; |
WiredHome | 0:e8e62dfee5eb | 702 | i += *buf - '0'; |
WiredHome | 0:e8e62dfee5eb | 703 | } |
WiredHome | 0:e8e62dfee5eb | 704 | if (i < 1 || i > 12) |
WiredHome | 0:e8e62dfee5eb | 705 | return 0; |
WiredHome | 0:e8e62dfee5eb | 706 | |
WiredHome | 0:e8e62dfee5eb | 707 | tm->tm_mon = i - 1; |
WiredHome | 0:e8e62dfee5eb | 708 | |
WiredHome | 0:e8e62dfee5eb | 709 | if (*buf != 0 && isspace(*buf)) |
WiredHome | 0:e8e62dfee5eb | 710 | while (*ptr != 0 && !isspace(*ptr)) |
WiredHome | 0:e8e62dfee5eb | 711 | ptr++; |
WiredHome | 0:e8e62dfee5eb | 712 | break; |
WiredHome | 0:e8e62dfee5eb | 713 | |
WiredHome | 0:e8e62dfee5eb | 714 | case 'Y': |
WiredHome | 0:e8e62dfee5eb | 715 | case 'y': |
WiredHome | 0:e8e62dfee5eb | 716 | if (*buf == 0 || isspace(*buf)) |
WiredHome | 0:e8e62dfee5eb | 717 | break; |
WiredHome | 0:e8e62dfee5eb | 718 | |
WiredHome | 0:e8e62dfee5eb | 719 | if (!isdigit(*buf)) |
WiredHome | 0:e8e62dfee5eb | 720 | return 0; |
WiredHome | 0:e8e62dfee5eb | 721 | |
WiredHome | 0:e8e62dfee5eb | 722 | for (i = 0; *buf != 0 && isdigit(*buf); buf++) { |
WiredHome | 0:e8e62dfee5eb | 723 | i *= 10; |
WiredHome | 0:e8e62dfee5eb | 724 | i += *buf - '0'; |
WiredHome | 0:e8e62dfee5eb | 725 | } |
WiredHome | 0:e8e62dfee5eb | 726 | if (c == 'Y') |
WiredHome | 0:e8e62dfee5eb | 727 | i -= 1900; |
WiredHome | 0:e8e62dfee5eb | 728 | if (i < 0) |
WiredHome | 0:e8e62dfee5eb | 729 | return 0; |
WiredHome | 0:e8e62dfee5eb | 730 | |
WiredHome | 0:e8e62dfee5eb | 731 | tm->tm_year = i; |
WiredHome | 0:e8e62dfee5eb | 732 | |
WiredHome | 0:e8e62dfee5eb | 733 | if (*buf != 0 && isspace(*buf)) |
WiredHome | 0:e8e62dfee5eb | 734 | while (*ptr != 0 && !isspace(*ptr)) |
WiredHome | 0:e8e62dfee5eb | 735 | ptr++; |
WiredHome | 0:e8e62dfee5eb | 736 | break; |
WiredHome | 0:e8e62dfee5eb | 737 | case 'Z': |
WiredHome | 1:b78c91e34eda | 738 | for (ndx = 0; ndx < asizeof(En_US.zone_names); ndx++) { |
WiredHome | 1:b78c91e34eda | 739 | len = strlen(En_US.zone_names[ndx]); |
WiredHome | 1:b78c91e34eda | 740 | if (strncasecmp(buf, En_US.zone_names[ndx], len) == 0) |
WiredHome | 0:e8e62dfee5eb | 741 | break; |
WiredHome | 0:e8e62dfee5eb | 742 | } |
WiredHome | 1:b78c91e34eda | 743 | if (ndx == asizeof(En_US.zone_names)) |
WiredHome | 0:e8e62dfee5eb | 744 | return 0; |
WiredHome | 1:b78c91e34eda | 745 | tm->tm_tzo_min = En_US.zone_offsets[ndx] * 60; |
WiredHome | 0:e8e62dfee5eb | 746 | buf += len; |
WiredHome | 0:e8e62dfee5eb | 747 | break; |
WiredHome | 0:e8e62dfee5eb | 748 | } |
WiredHome | 0:e8e62dfee5eb | 749 | } |
WiredHome | 0:e8e62dfee5eb | 750 | if (!fSet_wday) { |
WiredHome | 0:e8e62dfee5eb | 751 | if (mktime(tm) == (time_t)-1) |
WiredHome | 0:e8e62dfee5eb | 752 | tm->tm_wday = 7; |
WiredHome | 0:e8e62dfee5eb | 753 | } |
WiredHome | 0:e8e62dfee5eb | 754 | return buf; |
WiredHome | 0:e8e62dfee5eb | 755 | } |