Simple time management w/o the Network interface

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?

UserRevisionLine numberNew 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 }