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.

Dependencies:   CalendarPage

Dependents:   CI-data-logger-server WattEye X10Svr SSDP_Server

Committer:
WiredHome
Date:
Wed Apr 03 22:26:47 2019 +0000
Revision:
30:2740e128a809
Parent:
26:9ee3fac64626
Modify asctime to include the dst flag in its processing, in addition to the tzo.

Who changed what in which revision?

UserRevisionLine numberNew 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 30:2740e128a809 198 if (tmp.tm_isdst)
WiredHome 30:2740e128a809 199 tmp.tm_min += 60;
WiredHome 10:5734dbc2f5cc 200 while (tmp.tm_min >= 60) {
WiredHome 10:5734dbc2f5cc 201 tmp.tm_min -= 60;
WiredHome 10:5734dbc2f5cc 202 tmp.tm_hour++;
WiredHome 10:5734dbc2f5cc 203 }
WiredHome 10:5734dbc2f5cc 204 while (tmp.tm_min < 0) {
WiredHome 10:5734dbc2f5cc 205 tmp.tm_min += 60;
WiredHome 10:5734dbc2f5cc 206 tmp.tm_hour--;
WiredHome 10:5734dbc2f5cc 207 }
WiredHome 10:5734dbc2f5cc 208 while (tmp.tm_hour >= 24) {
WiredHome 10:5734dbc2f5cc 209 tmp.tm_wday = (tmp.tm_wday + 1) % 7;
WiredHome 10:5734dbc2f5cc 210 tmp.tm_mday++;
WiredHome 10:5734dbc2f5cc 211 tmp.tm_hour -= 24;
WiredHome 10:5734dbc2f5cc 212 }
WiredHome 10:5734dbc2f5cc 213 while (tmp.tm_hour < 0) {
WiredHome 10:5734dbc2f5cc 214 tmp.tm_wday = (tmp.tm_wday + 6) % 7;
WiredHome 10:5734dbc2f5cc 215 tmp.tm_mday--;
WiredHome 10:5734dbc2f5cc 216 tmp.tm_hour += 24;
WiredHome 10:5734dbc2f5cc 217 }
WiredHome 0:61112ca9193b 218 sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d",
WiredHome 10:5734dbc2f5cc 219 wday_name[tmp.tm_wday % 7],
WiredHome 10:5734dbc2f5cc 220 mon_name[tmp.tm_mon % 12],
WiredHome 10:5734dbc2f5cc 221 tmp.tm_mday, tmp.tm_hour,
WiredHome 10:5734dbc2f5cc 222 tmp.tm_min, tmp.tm_sec,
WiredHome 10:5734dbc2f5cc 223 1900 + tmp.tm_year);
WiredHome 0:61112ca9193b 224 return result;
WiredHome 0:61112ca9193b 225 }
WiredHome 0:61112ca9193b 226
WiredHome 11:1d880a50da8a 227 struct tm_ex * TimeInterface::gmtime(const time_t * timer)
WiredHome 11:1d880a50da8a 228 {
WiredHome 7:1de342fa7840 229 time_t priv = *timer + get_tzo_min() * 60 + dst * 3600;
WiredHome 0:61112ca9193b 230 struct tm * tmp = std::localtime(&priv);
WiredHome 10:5734dbc2f5cc 231
WiredHome 0:61112ca9193b 232 tm_ext.tm_sec = tmp->tm_sec;
WiredHome 0:61112ca9193b 233 tm_ext.tm_min = tmp->tm_min;
WiredHome 0:61112ca9193b 234 tm_ext.tm_hour = tmp->tm_hour;
WiredHome 0:61112ca9193b 235 tm_ext.tm_mday = tmp->tm_mday;
WiredHome 0:61112ca9193b 236 tm_ext.tm_mon = tmp->tm_mon;
WiredHome 0:61112ca9193b 237 tm_ext.tm_year = tmp->tm_year;
WiredHome 0:61112ca9193b 238 tm_ext.tm_wday = tmp->tm_wday;
WiredHome 0:61112ca9193b 239 tm_ext.tm_yday = tmp->tm_yday;
WiredHome 0:61112ca9193b 240 tm_ext.tm_isdst = tmp->tm_isdst;
WiredHome 0:61112ca9193b 241 tm_ext.tm_tzo_min = get_tzo_min();
WiredHome 0:61112ca9193b 242 return &tm_ext;
WiredHome 0:61112ca9193b 243 }
WiredHome 0:61112ca9193b 244
WiredHome 11:1d880a50da8a 245 struct tm_ex * TimeInterface::localtime(const time_t * timer)
WiredHome 11:1d880a50da8a 246 {
WiredHome 0:61112ca9193b 247 struct tm * tmp = std::localtime(timer);
WiredHome 10:5734dbc2f5cc 248
WiredHome 0:61112ca9193b 249 tm_ext.tm_sec = tmp->tm_sec;
WiredHome 0:61112ca9193b 250 tm_ext.tm_min = tmp->tm_min;
WiredHome 0:61112ca9193b 251 tm_ext.tm_hour = tmp->tm_hour;
WiredHome 0:61112ca9193b 252 tm_ext.tm_mday = tmp->tm_mday;
WiredHome 0:61112ca9193b 253 tm_ext.tm_mon = tmp->tm_mon;
WiredHome 0:61112ca9193b 254 tm_ext.tm_year = tmp->tm_year;
WiredHome 0:61112ca9193b 255 tm_ext.tm_wday = tmp->tm_wday;
WiredHome 0:61112ca9193b 256 tm_ext.tm_yday = tmp->tm_yday;
WiredHome 0:61112ca9193b 257 tm_ext.tm_isdst = tmp->tm_isdst;
WiredHome 0:61112ca9193b 258 tm_ext.tm_tzo_min = get_tzo_min();
WiredHome 0:61112ca9193b 259 return &tm_ext;
WiredHome 0:61112ca9193b 260 }
WiredHome 0:61112ca9193b 261
WiredHome 0:61112ca9193b 262 time_t TimeInterface::mktime(struct tm_ex * timeptr)
WiredHome 0:61112ca9193b 263 {
WiredHome 26:9ee3fac64626 264 timeptr->tm_tzo_min = get_tzo_min();
WiredHome 0:61112ca9193b 265 return std::mktime((struct tm *)timeptr);
WiredHome 0:61112ca9193b 266 }
WiredHome 0:61112ca9193b 267
WiredHome 0:61112ca9193b 268 size_t TimeInterface::strftime(char * ptr, size_t maxsize, const char * format, const struct tm_ex * timeptr)
WiredHome 0:61112ca9193b 269 {
WiredHome 0:61112ca9193b 270 return std::strftime(ptr, maxsize, format, (struct tm *)timeptr);
WiredHome 0:61112ca9193b 271 }
WiredHome 0:61112ca9193b 272
WiredHome 0:61112ca9193b 273 double TimeInterface::difftime(time_t end, time_t beginning)
WiredHome 0:61112ca9193b 274 {
WiredHome 0:61112ca9193b 275 return std::difftime(end, beginning);
WiredHome 0:61112ca9193b 276 }
WiredHome 0:61112ca9193b 277
WiredHome 0:61112ca9193b 278
WiredHome 0:61112ca9193b 279
WiredHome 0:61112ca9193b 280 // time zone functions
WiredHome 0:61112ca9193b 281
WiredHome 0:61112ca9193b 282 void TimeInterface::set_time(time_t t, int16_t tzo_min)
WiredHome 0:61112ca9193b 283 {
WiredHome 2:65e0a25c7551 284 time_t tval = t - (tzo_min * 60);
WiredHome 0:61112ca9193b 285 rtc_init();
WiredHome 0:61112ca9193b 286 rtc_write(tval);
WiredHome 0:61112ca9193b 287 LPC_RTC->GPREG1 = tval;
WiredHome 2:65e0a25c7551 288 INFO("set_time(%s)", ctime(&tval));
WiredHome 0:61112ca9193b 289 }
WiredHome 0:61112ca9193b 290
WiredHome 0:61112ca9193b 291 void TimeInterface::set_tzo_min(int16_t tzo_min)
WiredHome 0:61112ca9193b 292 {
WiredHome 0:61112ca9193b 293 uint16_t th;
WiredHome 0:61112ca9193b 294 uint32_t treg;
WiredHome 10:5734dbc2f5cc 295
WiredHome 0:61112ca9193b 296 if (tzo_min >= -720 && tzo_min <= 720) {
WiredHome 0:61112ca9193b 297 th = (uint16_t)(-tzo_min);
WiredHome 0:61112ca9193b 298 treg = (th << 16) | (uint16_t)tzo_min;
WiredHome 0:61112ca9193b 299 LPC_RTC->GPREG0 = treg;
WiredHome 0:61112ca9193b 300 //printf("set_tzo(%d) %d is %08X\r\n", tzo, th, LPC_RTC->GPREG0);
WiredHome 0:61112ca9193b 301 }
WiredHome 0:61112ca9193b 302 }
WiredHome 0:61112ca9193b 303
WiredHome 0:61112ca9193b 304 int16_t TimeInterface::get_tzo_min(void)
WiredHome 0:61112ca9193b 305 {
WiredHome 0:61112ca9193b 306 uint16_t th, tl;
WiredHome 10:5734dbc2f5cc 307
WiredHome 0:61112ca9193b 308 th = LPC_RTC->GPREG0 >> 16;
WiredHome 0:61112ca9193b 309 tl = LPC_RTC->GPREG0;
WiredHome 0:61112ca9193b 310 //printf("get_tzo() is %04X %04X\r\n", th, tl);
WiredHome 0:61112ca9193b 311 if ((uint16_t)(th + tl) == 0) {
WiredHome 0:61112ca9193b 312 return tl;
WiredHome 0:61112ca9193b 313 } else {
WiredHome 0:61112ca9193b 314 return 0;
WiredHome 0:61112ca9193b 315 }
WiredHome 0:61112ca9193b 316 }
WiredHome 0:61112ca9193b 317
WiredHome 0:61112ca9193b 318 time_t TimeInterface::get_timelastset(void)
WiredHome 0:61112ca9193b 319 {
WiredHome 0:61112ca9193b 320 return LPC_RTC->GPREG1;
WiredHome 0:61112ca9193b 321 }
WiredHome 0:61112ca9193b 322
WiredHome 10:5734dbc2f5cc 323 int32_t TimeInterface::get_cal()
WiredHome 10:5734dbc2f5cc 324 {
WiredHome 0:61112ca9193b 325 int32_t calvalue = LPC_RTC->CALIBRATION & 0x3FFFF;
WiredHome 0:61112ca9193b 326
WiredHome 0:61112ca9193b 327 if (calvalue & 0x20000) {
WiredHome 0:61112ca9193b 328 calvalue = -(calvalue & 0x1FFFF);
WiredHome 10:5734dbc2f5cc 329 }
WiredHome 0:61112ca9193b 330 return calvalue;
WiredHome 0:61112ca9193b 331 }
WiredHome 0:61112ca9193b 332
WiredHome 10:5734dbc2f5cc 333 void TimeInterface::set_cal(int32_t calibration)
WiredHome 10:5734dbc2f5cc 334 {
WiredHome 0:61112ca9193b 335 if (calibration) {
WiredHome 0:61112ca9193b 336 if (calibration < 0) {
WiredHome 0:61112ca9193b 337 calibration = (-calibration & 0x1FFFF) | 0x20000;
WiredHome 0:61112ca9193b 338 }
WiredHome 0:61112ca9193b 339 LPC_RTC->CCR = 0x000001; //(LPC_RTC->CCR & 0x0003); // Clear CCALEN to enable it
WiredHome 0:61112ca9193b 340 } else {
WiredHome 0:61112ca9193b 341 LPC_RTC->CCR = 0x000011; //(LPC_RTC->CCR & 0x0003) | 0x0010; // Set CCALEN to disable it
WiredHome 0:61112ca9193b 342 }
WiredHome 0:61112ca9193b 343 LPC_RTC->CALIBRATION = calibration;
WiredHome 0:61112ca9193b 344 }
WiredHome 0:61112ca9193b 345
WiredHome 0:61112ca9193b 346 bool TimeInterface::adjust_sec(int32_t adjustSeconds)
WiredHome 0:61112ca9193b 347 {
WiredHome 0:61112ca9193b 348 time_t lastSet = get_timelastset();
WiredHome 10:5734dbc2f5cc 349
WiredHome 0:61112ca9193b 350 if (lastSet != 0) {
WiredHome 0:61112ca9193b 351 time_t seconds = time(NULL); // get "now" according to the rtc
WiredHome 0:61112ca9193b 352 int32_t delta = seconds - lastSet;
WiredHome 5:a5f50b5fb856 353 //int32_t curCal = get_cal(); // calibration might want to leverage the current cal factor.
WiredHome 0:61112ca9193b 354 int32_t calMAX = 131071;
WiredHome 0:61112ca9193b 355 int32_t secPerDay = 86400;
WiredHome 0:61112ca9193b 356 float errSecPerDay;
WiredHome 10:5734dbc2f5cc 357
WiredHome 0:61112ca9193b 358 // Convert the current calibration and the adjustment into
WiredHome 0:61112ca9193b 359 // the new calibration value
WiredHome 0:61112ca9193b 360 // assume it is +10sec and it has been 2days, then the adjustment
WiredHome 10:5734dbc2f5cc 361 // needs to be +5 sec per day, or one adjustment every 1/5th
WiredHome 0:61112ca9193b 362 // of a day, or 1 adjustment every 86400/5 counts.
WiredHome 0:61112ca9193b 363 // delta = now - then (number of elapsed seconds)
WiredHome 0:61112ca9193b 364 if (adjustSeconds != 0 && delta != 0) {
WiredHome 0:61112ca9193b 365 int32_t calFactor;
WiredHome 0:61112ca9193b 366
WiredHome 0:61112ca9193b 367 // Make the clock correct
WiredHome 0:61112ca9193b 368 seconds = seconds + adjustSeconds;
WiredHome 0:61112ca9193b 369 set_time(seconds);
WiredHome 0:61112ca9193b 370 // Compute the calibration factor
WiredHome 0:61112ca9193b 371 errSecPerDay = (float)adjustSeconds / ((float)(delta)/secPerDay);
WiredHome 0:61112ca9193b 372 calFactor = (int32_t)((float)secPerDay/errSecPerDay);
WiredHome 0:61112ca9193b 373 if (abs(calFactor) < calMAX)
WiredHome 0:61112ca9193b 374 set_cal(calFactor);
WiredHome 0:61112ca9193b 375 }
WiredHome 0:61112ca9193b 376 return true;
WiredHome 0:61112ca9193b 377 } else {
WiredHome 0:61112ca9193b 378 return false;
WiredHome 0:61112ca9193b 379 }
WiredHome 0:61112ca9193b 380 }
WiredHome 10:5734dbc2f5cc 381
WiredHome 10:5734dbc2f5cc 382
WiredHome 10:5734dbc2f5cc 383 // #############################################################################
WiredHome 10:5734dbc2f5cc 384 /*
WiredHome 10:5734dbc2f5cc 385 * Enhancement to use a custom tm_ex struct and the time zone by D. Smart
WiredHome 10:5734dbc2f5cc 386 * %Z
WiredHome 10:5734dbc2f5cc 387 *
WiredHome 10:5734dbc2f5cc 388 * Copyright (c) 1994 Powerdog Industries. All rights reserved.
WiredHome 10:5734dbc2f5cc 389 *
WiredHome 10:5734dbc2f5cc 390 * Redistribution and use in source and binary forms, without
WiredHome 10:5734dbc2f5cc 391 * modification, are permitted provided that the following conditions
WiredHome 10:5734dbc2f5cc 392 * are met:
WiredHome 10:5734dbc2f5cc 393 * 1. Redistributions of source code must retain the above copyright
WiredHome 10:5734dbc2f5cc 394 * notice, this list of conditions and the following disclaimer.
WiredHome 10:5734dbc2f5cc 395 * 2. Redistributions in binary form must reproduce the above copyright
WiredHome 10:5734dbc2f5cc 396 * notice, this list of conditions and the following disclaimer
WiredHome 10:5734dbc2f5cc 397 * in the documentation and/or other materials provided with the
WiredHome 10:5734dbc2f5cc 398 * distribution.
WiredHome 10:5734dbc2f5cc 399 * 3. All advertising materials mentioning features or use of this
WiredHome 10:5734dbc2f5cc 400 * software must display the following acknowledgement:
WiredHome 10:5734dbc2f5cc 401 * This product includes software developed by Powerdog Industries.
WiredHome 10:5734dbc2f5cc 402 * 4. The name of Powerdog Industries may not be used to endorse or
WiredHome 10:5734dbc2f5cc 403 * promote products derived from this software without specific prior
WiredHome 10:5734dbc2f5cc 404 * written permission.
WiredHome 10:5734dbc2f5cc 405 *
WiredHome 10:5734dbc2f5cc 406 * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``AS IS'' AND ANY
WiredHome 10:5734dbc2f5cc 407 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
WiredHome 10:5734dbc2f5cc 408 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
WiredHome 10:5734dbc2f5cc 409 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE POWERDOG INDUSTRIES BE
WiredHome 10:5734dbc2f5cc 410 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
WiredHome 10:5734dbc2f5cc 411 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
WiredHome 10:5734dbc2f5cc 412 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
WiredHome 10:5734dbc2f5cc 413 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WiredHome 10:5734dbc2f5cc 414 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
WiredHome 10:5734dbc2f5cc 415 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
WiredHome 10:5734dbc2f5cc 416 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
WiredHome 10:5734dbc2f5cc 417 */
WiredHome 10:5734dbc2f5cc 418
WiredHome 10:5734dbc2f5cc 419 #define asizeof(a) (sizeof (a) / sizeof ((a)[0]))
WiredHome 10:5734dbc2f5cc 420
WiredHome 10:5734dbc2f5cc 421 struct dtconv {
WiredHome 10:5734dbc2f5cc 422 char *abbrev_month_names[12];
WiredHome 10:5734dbc2f5cc 423 char *month_names[12];
WiredHome 10:5734dbc2f5cc 424 char *abbrev_weekday_names[7];
WiredHome 10:5734dbc2f5cc 425 char *weekday_names[7];
WiredHome 10:5734dbc2f5cc 426 char *time_format;
WiredHome 10:5734dbc2f5cc 427 char *sdate_format;
WiredHome 10:5734dbc2f5cc 428 char *dtime_format;
WiredHome 10:5734dbc2f5cc 429 char *am_string;
WiredHome 10:5734dbc2f5cc 430 char *pm_string;
WiredHome 10:5734dbc2f5cc 431 char *ldate_format;
WiredHome 11:1d880a50da8a 432 char *zone_names[10];
WiredHome 11:1d880a50da8a 433 int8_t zone_offsets[10];
WiredHome 10:5734dbc2f5cc 434 };
WiredHome 10:5734dbc2f5cc 435
WiredHome 19:ccdf8b6f6aa1 436 static const struct dtconv En_US = {
WiredHome 10:5734dbc2f5cc 437 {
WiredHome 10:5734dbc2f5cc 438 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
WiredHome 10:5734dbc2f5cc 439 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
WiredHome 10:5734dbc2f5cc 440 },
WiredHome 10:5734dbc2f5cc 441 {
WiredHome 10:5734dbc2f5cc 442 "January", "February", "March", "April",
WiredHome 10:5734dbc2f5cc 443 "May", "June", "July", "August",
WiredHome 10:5734dbc2f5cc 444 "September", "October", "November", "December"
WiredHome 10:5734dbc2f5cc 445 },
WiredHome 10:5734dbc2f5cc 446 { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" },
WiredHome 10:5734dbc2f5cc 447 {
WiredHome 10:5734dbc2f5cc 448 "Sunday", "Monday", "Tuesday", "Wednesday",
WiredHome 10:5734dbc2f5cc 449 "Thursday", "Friday", "Saturday"
WiredHome 10:5734dbc2f5cc 450 },
WiredHome 10:5734dbc2f5cc 451 "%H:%M:%S",
WiredHome 10:5734dbc2f5cc 452 "%m/%d/%y",
WiredHome 10:5734dbc2f5cc 453 "%a %b %e %T %Z %Y",
WiredHome 10:5734dbc2f5cc 454 "AM",
WiredHome 10:5734dbc2f5cc 455 "PM",
WiredHome 10:5734dbc2f5cc 456 "%A, %B, %e, %Y",
WiredHome 11:1d880a50da8a 457 { "UTC", "EST", "CST", "MST", "PST", "YST", "CAT", "HST", "CET", "EET", },
WiredHome 11:1d880a50da8a 458 { 0, -5, -6, -7, -8, -9, -10, -10, +1, +2, },
WiredHome 10:5734dbc2f5cc 459 };
WiredHome 10:5734dbc2f5cc 460
WiredHome 11:1d880a50da8a 461
WiredHome 10:5734dbc2f5cc 462 #ifndef isprint
WiredHome 20:5ca2c94d46b8 463 #define in_range(c, lo, up) ((uint8_t)c >= lo && (uint8_t)c <= up)
WiredHome 10:5734dbc2f5cc 464 #define isprint(c) in_range(c, 0x20, 0x7f)
WiredHome 10:5734dbc2f5cc 465 #define isdigit(c) in_range(c, '0', '9')
WiredHome 10:5734dbc2f5cc 466 #define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))
WiredHome 10:5734dbc2f5cc 467 #define islower(c) in_range(c, 'a', 'z')
WiredHome 10:5734dbc2f5cc 468 #define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
WiredHome 10:5734dbc2f5cc 469 #endif
WiredHome 10:5734dbc2f5cc 470
WiredHome 10:5734dbc2f5cc 471
WiredHome 10:5734dbc2f5cc 472 const char * TimeInterface::strptime(const char *buf, char *fmt, struct tm_ex *tm)
WiredHome 10:5734dbc2f5cc 473 {
WiredHome 10:5734dbc2f5cc 474 char c, *ptr;
WiredHome 10:5734dbc2f5cc 475 int i, len;
WiredHome 18:dcd46f9e98fa 476 bool fSet_wday = false; // so we can notice if the wday was set
WiredHome 18:dcd46f9e98fa 477
WiredHome 10:5734dbc2f5cc 478 ptr = fmt;
WiredHome 10:5734dbc2f5cc 479 while (*ptr != 0) {
WiredHome 10:5734dbc2f5cc 480 if (*buf == 0)
WiredHome 10:5734dbc2f5cc 481 break;
WiredHome 10:5734dbc2f5cc 482
WiredHome 10:5734dbc2f5cc 483 c = *ptr++;
WiredHome 10:5734dbc2f5cc 484
WiredHome 10:5734dbc2f5cc 485 if (c != '%') {
WiredHome 10:5734dbc2f5cc 486 if (isspace(c))
WiredHome 10:5734dbc2f5cc 487 while (*buf != 0 && isspace(*buf))
WiredHome 10:5734dbc2f5cc 488 buf++;
WiredHome 10:5734dbc2f5cc 489 else if (c != *buf++)
WiredHome 10:5734dbc2f5cc 490 return 0;
WiredHome 10:5734dbc2f5cc 491 continue;
WiredHome 10:5734dbc2f5cc 492 }
WiredHome 10:5734dbc2f5cc 493
WiredHome 10:5734dbc2f5cc 494 c = *ptr++;
WiredHome 10:5734dbc2f5cc 495 switch (c) {
WiredHome 10:5734dbc2f5cc 496 case 0:
WiredHome 10:5734dbc2f5cc 497 case '%':
WiredHome 10:5734dbc2f5cc 498 if (*buf++ != '%')
WiredHome 10:5734dbc2f5cc 499 return 0;
WiredHome 10:5734dbc2f5cc 500 break;
WiredHome 10:5734dbc2f5cc 501
WiredHome 10:5734dbc2f5cc 502 case 'C':
WiredHome 10:5734dbc2f5cc 503 buf = strptime(buf, En_US.ldate_format, tm);
WiredHome 10:5734dbc2f5cc 504 if (buf == 0)
WiredHome 10:5734dbc2f5cc 505 return 0;
WiredHome 10:5734dbc2f5cc 506 break;
WiredHome 10:5734dbc2f5cc 507
WiredHome 10:5734dbc2f5cc 508 case 'c':
WiredHome 10:5734dbc2f5cc 509 buf = strptime(buf, "%x %X", tm);
WiredHome 10:5734dbc2f5cc 510 if (buf == 0)
WiredHome 10:5734dbc2f5cc 511 return 0;
WiredHome 10:5734dbc2f5cc 512 break;
WiredHome 10:5734dbc2f5cc 513
WiredHome 10:5734dbc2f5cc 514 case 'D':
WiredHome 10:5734dbc2f5cc 515 buf = strptime(buf, "%m/%d/%y", tm);
WiredHome 10:5734dbc2f5cc 516 if (buf == 0)
WiredHome 10:5734dbc2f5cc 517 return 0;
WiredHome 10:5734dbc2f5cc 518 break;
WiredHome 10:5734dbc2f5cc 519
WiredHome 10:5734dbc2f5cc 520 case 'R':
WiredHome 10:5734dbc2f5cc 521 buf = strptime(buf, "%H:%M", tm);
WiredHome 10:5734dbc2f5cc 522 if (buf == 0)
WiredHome 10:5734dbc2f5cc 523 return 0;
WiredHome 10:5734dbc2f5cc 524 break;
WiredHome 10:5734dbc2f5cc 525
WiredHome 10:5734dbc2f5cc 526 case 'r':
WiredHome 10:5734dbc2f5cc 527 buf = strptime(buf, "%I:%M:%S %p", tm);
WiredHome 10:5734dbc2f5cc 528 if (buf == 0)
WiredHome 10:5734dbc2f5cc 529 return 0;
WiredHome 10:5734dbc2f5cc 530 break;
WiredHome 10:5734dbc2f5cc 531
WiredHome 10:5734dbc2f5cc 532 case 'T':
WiredHome 10:5734dbc2f5cc 533 buf = strptime(buf, "%H:%M:%S", tm);
WiredHome 10:5734dbc2f5cc 534 if (buf == 0)
WiredHome 10:5734dbc2f5cc 535 return 0;
WiredHome 10:5734dbc2f5cc 536 break;
WiredHome 10:5734dbc2f5cc 537
WiredHome 10:5734dbc2f5cc 538 case 'X':
WiredHome 10:5734dbc2f5cc 539 buf = strptime(buf, En_US.time_format, tm);
WiredHome 10:5734dbc2f5cc 540 if (buf == 0)
WiredHome 10:5734dbc2f5cc 541 return 0;
WiredHome 10:5734dbc2f5cc 542 break;
WiredHome 10:5734dbc2f5cc 543
WiredHome 10:5734dbc2f5cc 544 case 'x':
WiredHome 10:5734dbc2f5cc 545 buf = strptime(buf, En_US.sdate_format, tm);
WiredHome 10:5734dbc2f5cc 546 if (buf == 0)
WiredHome 10:5734dbc2f5cc 547 return 0;
WiredHome 10:5734dbc2f5cc 548 break;
WiredHome 10:5734dbc2f5cc 549
WiredHome 10:5734dbc2f5cc 550 case 'j':
WiredHome 10:5734dbc2f5cc 551 if (!isdigit(*buf))
WiredHome 10:5734dbc2f5cc 552 return 0;
WiredHome 10:5734dbc2f5cc 553
WiredHome 10:5734dbc2f5cc 554 for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
WiredHome 10:5734dbc2f5cc 555 i *= 10;
WiredHome 10:5734dbc2f5cc 556 i += *buf - '0';
WiredHome 10:5734dbc2f5cc 557 }
WiredHome 10:5734dbc2f5cc 558 if (i > 365)
WiredHome 10:5734dbc2f5cc 559 return 0;
WiredHome 10:5734dbc2f5cc 560
WiredHome 10:5734dbc2f5cc 561 tm->tm_yday = i;
WiredHome 10:5734dbc2f5cc 562 break;
WiredHome 10:5734dbc2f5cc 563
WiredHome 10:5734dbc2f5cc 564 case 'M':
WiredHome 10:5734dbc2f5cc 565 case 'S':
WiredHome 10:5734dbc2f5cc 566 if (*buf == 0 || isspace(*buf))
WiredHome 10:5734dbc2f5cc 567 break;
WiredHome 10:5734dbc2f5cc 568
WiredHome 10:5734dbc2f5cc 569 if (!isdigit(*buf))
WiredHome 10:5734dbc2f5cc 570 return 0;
WiredHome 10:5734dbc2f5cc 571
WiredHome 10:5734dbc2f5cc 572 for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
WiredHome 10:5734dbc2f5cc 573 i *= 10;
WiredHome 10:5734dbc2f5cc 574 i += *buf - '0';
WiredHome 10:5734dbc2f5cc 575 }
WiredHome 10:5734dbc2f5cc 576 if (i > 59)
WiredHome 10:5734dbc2f5cc 577 return 0;
WiredHome 10:5734dbc2f5cc 578
WiredHome 10:5734dbc2f5cc 579 if (c == 'M')
WiredHome 10:5734dbc2f5cc 580 tm->tm_min = i;
WiredHome 10:5734dbc2f5cc 581 else
WiredHome 10:5734dbc2f5cc 582 tm->tm_sec = i;
WiredHome 10:5734dbc2f5cc 583
WiredHome 10:5734dbc2f5cc 584 if (*buf != 0 && isspace(*buf))
WiredHome 10:5734dbc2f5cc 585 while (*ptr != 0 && !isspace(*ptr))
WiredHome 10:5734dbc2f5cc 586 ptr++;
WiredHome 10:5734dbc2f5cc 587 break;
WiredHome 10:5734dbc2f5cc 588
WiredHome 10:5734dbc2f5cc 589 case 'H':
WiredHome 10:5734dbc2f5cc 590 case 'I':
WiredHome 10:5734dbc2f5cc 591 case 'k':
WiredHome 10:5734dbc2f5cc 592 case 'l':
WiredHome 10:5734dbc2f5cc 593 if (!isdigit(*buf))
WiredHome 10:5734dbc2f5cc 594 return 0;
WiredHome 10:5734dbc2f5cc 595
WiredHome 10:5734dbc2f5cc 596 for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
WiredHome 10:5734dbc2f5cc 597 i *= 10;
WiredHome 10:5734dbc2f5cc 598 i += *buf - '0';
WiredHome 10:5734dbc2f5cc 599 }
WiredHome 10:5734dbc2f5cc 600 if (c == 'H' || c == 'k') {
WiredHome 10:5734dbc2f5cc 601 if (i > 23)
WiredHome 10:5734dbc2f5cc 602 return 0;
WiredHome 10:5734dbc2f5cc 603 } else if (i > 11)
WiredHome 10:5734dbc2f5cc 604 return 0;
WiredHome 10:5734dbc2f5cc 605
WiredHome 10:5734dbc2f5cc 606 tm->tm_hour = i;
WiredHome 10:5734dbc2f5cc 607
WiredHome 10:5734dbc2f5cc 608 if (*buf != 0 && isspace(*buf))
WiredHome 10:5734dbc2f5cc 609 while (*ptr != 0 && !isspace(*ptr))
WiredHome 10:5734dbc2f5cc 610 ptr++;
WiredHome 10:5734dbc2f5cc 611 break;
WiredHome 10:5734dbc2f5cc 612
WiredHome 10:5734dbc2f5cc 613 case 'p':
WiredHome 10:5734dbc2f5cc 614 len = strlen(En_US.am_string);
WiredHome 10:5734dbc2f5cc 615 if (strncasecmp(buf, En_US.am_string, len) == 0) {
WiredHome 10:5734dbc2f5cc 616 if (tm->tm_hour > 12)
WiredHome 10:5734dbc2f5cc 617 return 0;
WiredHome 10:5734dbc2f5cc 618 if (tm->tm_hour == 12)
WiredHome 10:5734dbc2f5cc 619 tm->tm_hour = 0;
WiredHome 10:5734dbc2f5cc 620 buf += len;
WiredHome 10:5734dbc2f5cc 621 break;
WiredHome 10:5734dbc2f5cc 622 }
WiredHome 10:5734dbc2f5cc 623
WiredHome 10:5734dbc2f5cc 624 len = strlen(En_US.pm_string);
WiredHome 10:5734dbc2f5cc 625 if (strncasecmp(buf, En_US.pm_string, len) == 0) {
WiredHome 10:5734dbc2f5cc 626 if (tm->tm_hour > 12)
WiredHome 10:5734dbc2f5cc 627 return 0;
WiredHome 10:5734dbc2f5cc 628 if (tm->tm_hour != 12)
WiredHome 10:5734dbc2f5cc 629 tm->tm_hour += 12;
WiredHome 10:5734dbc2f5cc 630 buf += len;
WiredHome 10:5734dbc2f5cc 631 break;
WiredHome 10:5734dbc2f5cc 632 }
WiredHome 10:5734dbc2f5cc 633
WiredHome 10:5734dbc2f5cc 634 return 0;
WiredHome 10:5734dbc2f5cc 635
WiredHome 10:5734dbc2f5cc 636 case 'A':
WiredHome 10:5734dbc2f5cc 637 case 'a':
WiredHome 10:5734dbc2f5cc 638 for (i = 0; i < asizeof(En_US.weekday_names); i++) {
WiredHome 10:5734dbc2f5cc 639 len = strlen(En_US.weekday_names[i]);
WiredHome 10:5734dbc2f5cc 640 if (strncasecmp(buf,
WiredHome 10:5734dbc2f5cc 641 En_US.weekday_names[i],
WiredHome 10:5734dbc2f5cc 642 len) == 0)
WiredHome 10:5734dbc2f5cc 643 break;
WiredHome 10:5734dbc2f5cc 644
WiredHome 10:5734dbc2f5cc 645 len = strlen(En_US.abbrev_weekday_names[i]);
WiredHome 10:5734dbc2f5cc 646 if (strncasecmp(buf,
WiredHome 10:5734dbc2f5cc 647 En_US.abbrev_weekday_names[i],
WiredHome 10:5734dbc2f5cc 648 len) == 0)
WiredHome 10:5734dbc2f5cc 649 break;
WiredHome 10:5734dbc2f5cc 650 }
WiredHome 10:5734dbc2f5cc 651 if (i == asizeof(En_US.weekday_names))
WiredHome 10:5734dbc2f5cc 652 return 0;
WiredHome 18:dcd46f9e98fa 653 fSet_wday = true;
WiredHome 10:5734dbc2f5cc 654 tm->tm_wday = i;
WiredHome 10:5734dbc2f5cc 655 buf += len;
WiredHome 10:5734dbc2f5cc 656 break;
WiredHome 10:5734dbc2f5cc 657
WiredHome 10:5734dbc2f5cc 658 case 'd':
WiredHome 10:5734dbc2f5cc 659 case 'e':
WiredHome 10:5734dbc2f5cc 660 if (!isdigit(*buf))
WiredHome 10:5734dbc2f5cc 661 return 0;
WiredHome 10:5734dbc2f5cc 662
WiredHome 10:5734dbc2f5cc 663 for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
WiredHome 10:5734dbc2f5cc 664 i *= 10;
WiredHome 10:5734dbc2f5cc 665 i += *buf - '0';
WiredHome 10:5734dbc2f5cc 666 }
WiredHome 10:5734dbc2f5cc 667 if (i > 31)
WiredHome 10:5734dbc2f5cc 668 return 0;
WiredHome 10:5734dbc2f5cc 669
WiredHome 10:5734dbc2f5cc 670 tm->tm_mday = i;
WiredHome 10:5734dbc2f5cc 671
WiredHome 10:5734dbc2f5cc 672 if (*buf != 0 && isspace(*buf))
WiredHome 10:5734dbc2f5cc 673 while (*ptr != 0 && !isspace(*ptr))
WiredHome 10:5734dbc2f5cc 674 ptr++;
WiredHome 10:5734dbc2f5cc 675 break;
WiredHome 10:5734dbc2f5cc 676
WiredHome 10:5734dbc2f5cc 677 case 'B':
WiredHome 10:5734dbc2f5cc 678 case 'b':
WiredHome 10:5734dbc2f5cc 679 case 'h':
WiredHome 10:5734dbc2f5cc 680 for (i = 0; i < asizeof(En_US.month_names); i++) {
WiredHome 10:5734dbc2f5cc 681 len = strlen(En_US.month_names[i]);
WiredHome 10:5734dbc2f5cc 682 if (strncasecmp(buf,
WiredHome 10:5734dbc2f5cc 683 En_US.month_names[i],
WiredHome 10:5734dbc2f5cc 684 len) == 0)
WiredHome 10:5734dbc2f5cc 685 break;
WiredHome 10:5734dbc2f5cc 686
WiredHome 10:5734dbc2f5cc 687 len = strlen(En_US.abbrev_month_names[i]);
WiredHome 10:5734dbc2f5cc 688 if (strncasecmp(buf,
WiredHome 10:5734dbc2f5cc 689 En_US.abbrev_month_names[i],
WiredHome 10:5734dbc2f5cc 690 len) == 0)
WiredHome 10:5734dbc2f5cc 691 break;
WiredHome 10:5734dbc2f5cc 692 }
WiredHome 10:5734dbc2f5cc 693 if (i == asizeof(En_US.month_names))
WiredHome 10:5734dbc2f5cc 694 return 0;
WiredHome 10:5734dbc2f5cc 695
WiredHome 10:5734dbc2f5cc 696 tm->tm_mon = i;
WiredHome 10:5734dbc2f5cc 697 buf += len;
WiredHome 10:5734dbc2f5cc 698 break;
WiredHome 10:5734dbc2f5cc 699
WiredHome 10:5734dbc2f5cc 700 case 'm':
WiredHome 10:5734dbc2f5cc 701 if (!isdigit(*buf))
WiredHome 10:5734dbc2f5cc 702 return 0;
WiredHome 10:5734dbc2f5cc 703
WiredHome 10:5734dbc2f5cc 704 for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
WiredHome 10:5734dbc2f5cc 705 i *= 10;
WiredHome 10:5734dbc2f5cc 706 i += *buf - '0';
WiredHome 10:5734dbc2f5cc 707 }
WiredHome 10:5734dbc2f5cc 708 if (i < 1 || i > 12)
WiredHome 10:5734dbc2f5cc 709 return 0;
WiredHome 10:5734dbc2f5cc 710
WiredHome 10:5734dbc2f5cc 711 tm->tm_mon = i - 1;
WiredHome 10:5734dbc2f5cc 712
WiredHome 10:5734dbc2f5cc 713 if (*buf != 0 && isspace(*buf))
WiredHome 10:5734dbc2f5cc 714 while (*ptr != 0 && !isspace(*ptr))
WiredHome 10:5734dbc2f5cc 715 ptr++;
WiredHome 10:5734dbc2f5cc 716 break;
WiredHome 10:5734dbc2f5cc 717
WiredHome 10:5734dbc2f5cc 718 case 'Y':
WiredHome 10:5734dbc2f5cc 719 case 'y':
WiredHome 10:5734dbc2f5cc 720 if (*buf == 0 || isspace(*buf))
WiredHome 10:5734dbc2f5cc 721 break;
WiredHome 10:5734dbc2f5cc 722
WiredHome 10:5734dbc2f5cc 723 if (!isdigit(*buf))
WiredHome 10:5734dbc2f5cc 724 return 0;
WiredHome 10:5734dbc2f5cc 725
WiredHome 10:5734dbc2f5cc 726 for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
WiredHome 10:5734dbc2f5cc 727 i *= 10;
WiredHome 10:5734dbc2f5cc 728 i += *buf - '0';
WiredHome 10:5734dbc2f5cc 729 }
WiredHome 10:5734dbc2f5cc 730 if (c == 'Y')
WiredHome 10:5734dbc2f5cc 731 i -= 1900;
WiredHome 10:5734dbc2f5cc 732 if (i < 0)
WiredHome 10:5734dbc2f5cc 733 return 0;
WiredHome 10:5734dbc2f5cc 734
WiredHome 10:5734dbc2f5cc 735 tm->tm_year = i;
WiredHome 10:5734dbc2f5cc 736
WiredHome 10:5734dbc2f5cc 737 if (*buf != 0 && isspace(*buf))
WiredHome 10:5734dbc2f5cc 738 while (*ptr != 0 && !isspace(*ptr))
WiredHome 10:5734dbc2f5cc 739 ptr++;
WiredHome 10:5734dbc2f5cc 740 break;
WiredHome 10:5734dbc2f5cc 741 case 'Z':
WiredHome 10:5734dbc2f5cc 742 for (i = 0; i < asizeof(En_US.zone_names); i++) {
WiredHome 10:5734dbc2f5cc 743 len = strlen(En_US.zone_names[i]);
WiredHome 10:5734dbc2f5cc 744 if (strncasecmp(buf,
WiredHome 10:5734dbc2f5cc 745 En_US.zone_names[i],
WiredHome 10:5734dbc2f5cc 746 len) == 0)
WiredHome 10:5734dbc2f5cc 747 break;
WiredHome 10:5734dbc2f5cc 748 }
WiredHome 10:5734dbc2f5cc 749 if (i == asizeof(En_US.zone_names))
WiredHome 10:5734dbc2f5cc 750 return 0;
WiredHome 10:5734dbc2f5cc 751 tm->tm_tzo_min = En_US.zone_offsets[i] * 60;
WiredHome 10:5734dbc2f5cc 752 buf += len;
WiredHome 10:5734dbc2f5cc 753 break;
WiredHome 10:5734dbc2f5cc 754 }
WiredHome 10:5734dbc2f5cc 755 }
WiredHome 18:dcd46f9e98fa 756 if (!fSet_wday) {
WiredHome 18:dcd46f9e98fa 757 if (mktime(tm) == (time_t)-1)
WiredHome 18:dcd46f9e98fa 758 tm->tm_wday = 7;
WiredHome 18:dcd46f9e98fa 759 }
WiredHome 10:5734dbc2f5cc 760 return buf;
WiredHome 10:5734dbc2f5cc 761 }