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