Simple time management w/o the Network interface
Embed:
(wiki syntax)
Show/hide line numbers
TimeInterface.cpp
00001 00002 #include "TimeInterface.h" 00003 00004 #include "rtc_api.h" 00005 00006 //#define DEBUG "Time" 00007 #include <cstdio> 00008 #if (defined(DEBUG) && !defined(TARGET_LPC11U24)) 00009 #define DBG(x, ...) std::printf("[DBG %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00010 #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00011 #define ERR(x, ...) std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00012 #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00013 #else 00014 #define DBG(x, ...) 00015 #define WARN(x, ...) 00016 #define ERR(x, ...) 00017 #define INFO(x, ...) 00018 #endif 00019 00020 #ifdef WIN32 00021 // Fake it out for Win32 development and testing 00022 struct LPC { 00023 unsigned long CCR; // Clock Control register 00024 unsigned long GPREG0; // General Purpose Register #0 - 32-bit Battery backed 00025 unsigned long GPREG1; // General Purpose Register #1 - 32-bit Battery backed 00026 unsigned long CALIBRATION; // Calibration Register 00027 }; 00028 struct LPC X; 00029 struct LPC * LPC_RTC = &X; 00030 #define set_time(x) (void)x 00031 #endif 00032 00033 00034 TimeInterface::TimeInterface(void *net) 00035 { 00036 m_net = net; 00037 dst = false; 00038 memset(&dst_pair, 0, sizeof(dst_pair)); // that's enough to keep it from running 00039 } 00040 00041 TimeInterface::~TimeInterface() 00042 { 00043 } 00044 00045 #if 0 00046 NTPResult TimeInterface::setTime(const char* host, uint16_t port, uint32_t timeout) 00047 { 00048 NTPResult res; 00049 00050 if (m_net) { 00051 NTPClient ntp(m_net); 00052 // int16_t tzomin = get_tzo_min(); 00053 INFO("setTime(%s, %d, %d)\r\n", host, port, timeout); 00054 res = ntp.setTime(host, port, timeout); 00055 INFO(" ret: %d\r\n", res); 00056 if (res == NTP_OK) { 00057 // if the time was fetched successfully, then 00058 // let's save the time last set with the local tzo applied 00059 // and this saves the last time set for later precision 00060 // tuning. 00061 set_time(std::time(NULL)); 00062 } 00063 } else { 00064 ERR("No connection"); 00065 res = NTP_CONN; 00066 } 00067 return res; 00068 } 00069 #endif 00070 00071 bool TimeInterface::parseDSTstring(TimeInterface::dst_event_t * result, const char * dstr) 00072 { 00073 int x; 00074 dst_event_t test_dst; 00075 00076 x = atoi(dstr); 00077 if (x >= 1 && x <= 12) { 00078 test_dst.MM = x; 00079 dstr = strchr(dstr, '/'); 00080 if (dstr++) { 00081 x = atoi(dstr); 00082 if (x >= 1 && x <= 31) { 00083 test_dst.DD = x; 00084 dstr = strchr(dstr, ','); 00085 if (dstr++) { 00086 x = atoi(dstr); 00087 if (x >= 0 && x <= 23) { 00088 test_dst.hh = x; 00089 dstr = strchr(dstr, ':'); 00090 if (dstr++) { 00091 x = atoi(dstr); 00092 if (x >= 0 && x <= 59) { 00093 test_dst.mm = x; 00094 memcpy(result, &test_dst, sizeof(dst_event_t)); 00095 INFO("parsed: %d/%d %d:%02d", test_dst.MM, test_dst.DD, test_dst.hh, test_dst.mm); 00096 return true; 00097 } 00098 } 00099 } 00100 } 00101 } 00102 } 00103 } 00104 return false; 00105 } 00106 00107 // parse MM/DD,hh:mm 00108 bool TimeInterface::set_dst(const char * dstStart, const char * dstStop) 00109 { 00110 dst_event_pair_t test_pair; 00111 00112 if (parseDSTstring(&test_pair.dst_start, dstStart) 00113 && parseDSTstring(&test_pair.dst_stop, dstStop)) { 00114 memcpy(&dst_pair, &test_pair, sizeof(dst_event_pair_t)); 00115 INFO("set_dst from (%s,%s)", dstStart, dstStop); 00116 return true; 00117 } 00118 WARN("failed to set_dst from (%s,%s)", dstStart, dstStop); 00119 return false; 00120 } 00121 00122 bool TimeInterface::set_dst(bool isdst) 00123 { 00124 dst = isdst; 00125 return true; 00126 } 00127 00128 bool TimeInterface::get_dst(void) 00129 { 00130 return dst; 00131 } 00132 00133 clock_t TimeInterface::clock(void) 00134 { 00135 return std::clock(); 00136 } 00137 00138 time_t TimeInterface::time(time_t * timer) 00139 { 00140 return std::time(timer); 00141 } 00142 00143 uint32_t TimeInterface::minutesSinceJan(int mon, int day, int hr, int min) 00144 { 00145 return (mon * 60 * 24 * 31) + (day * 60 * 24) + (hr * 60) + min; 00146 } 00147 00148 time_t TimeInterface::timelocal(time_t * timer) 00149 { 00150 time_t privTime; 00151 struct tm * tminfo; 00152 00153 if (dst_pair.dst_start.MM) { // may have to change the dst 00154 std::time(&privTime); 00155 tminfo = std::localtime(&privTime); 00156 00157 uint32_t min_since_jan = minutesSinceJan(tminfo->tm_mon + 1, tminfo->tm_mday, tminfo->tm_hour, tminfo->tm_min); 00158 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(); 00159 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(); 00160 00161 if (min_since_jan >= min_dst_start && min_since_jan < min_dst_stop) { 00162 dst = 1; 00163 //INFO(" is dst: %u - %u - %u", min_since_jan, min_dst_start, min_dst_stop); 00164 } else { 00165 dst = 0; 00166 //INFO("not dst: %u - %u - %u", min_since_jan, min_dst_start, min_dst_stop); 00167 } 00168 } 00169 INFO(" timelocal: %u, %d, %d", std::time(timer), get_tzo_min(), dst); 00170 return std::time(timer) + get_tzo_min() * 60 + dst * 3600; 00171 } 00172 00173 char * TimeInterface::ctime(const time_t * timer) 00174 { 00175 char * p = std::ctime(timer); 00176 00177 if (strlen(p) < sizeof(result)) { 00178 strcpy(result, p); 00179 p = strchr(result, '\n'); 00180 if (p) 00181 *p = '\0'; 00182 } else { 00183 result[0] = '\0'; 00184 } 00185 return result; 00186 } 00187 00188 char * TimeInterface::asctime(const struct tm_ex * timeptr) 00189 { 00190 static const char wday_name[][4] = { 00191 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 00192 }; 00193 static const char mon_name[][4] = { 00194 "Jan", "Feb", "Mar", "Apr", "May", "Jun", 00195 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 00196 }; 00197 struct tm_ex tmp = *timeptr; 00198 00199 tmp.tm_min += tmp.tm_tzo_min; 00200 if (tmp.tm_isdst) 00201 tmp.tm_min += 60; 00202 while (tmp.tm_min >= 60) { 00203 tmp.tm_min -= 60; 00204 tmp.tm_hour++; 00205 } 00206 while (tmp.tm_min < 0) { 00207 tmp.tm_min += 60; 00208 tmp.tm_hour--; 00209 } 00210 while (tmp.tm_hour >= 24) { 00211 tmp.tm_wday = (tmp.tm_wday + 1) % 7; 00212 tmp.tm_mday++; 00213 tmp.tm_hour -= 24; 00214 } 00215 while (tmp.tm_hour < 0) { 00216 tmp.tm_wday = (tmp.tm_wday + 6) % 7; 00217 tmp.tm_mday--; 00218 tmp.tm_hour += 24; 00219 } 00220 sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d", 00221 wday_name[tmp.tm_wday % 7], 00222 mon_name[tmp.tm_mon % 12], 00223 tmp.tm_mday % 99, tmp.tm_hour % 25, 00224 tmp.tm_min % 99, tmp.tm_sec % 99, 00225 1900 + tmp.tm_year); 00226 return result; 00227 } 00228 00229 struct tm_ex * TimeInterface::gmtime(const time_t * timer) 00230 { 00231 time_t priv = *timer + get_tzo_min() * 60 + dst * 3600; 00232 struct tm * tmp = std::localtime(&priv); 00233 00234 tm_ext.tm_sec = tmp->tm_sec; 00235 tm_ext.tm_min = tmp->tm_min; 00236 tm_ext.tm_hour = tmp->tm_hour; 00237 tm_ext.tm_mday = tmp->tm_mday; 00238 tm_ext.tm_mon = tmp->tm_mon; 00239 tm_ext.tm_year = tmp->tm_year; 00240 tm_ext.tm_wday = tmp->tm_wday; 00241 tm_ext.tm_yday = tmp->tm_yday; 00242 tm_ext.tm_isdst = tmp->tm_isdst; 00243 tm_ext.tm_tzo_min = get_tzo_min(); 00244 return &tm_ext; 00245 } 00246 00247 struct tm_ex * TimeInterface::localtime(const time_t * timer) 00248 { 00249 struct tm * tmp = std::localtime(timer); 00250 00251 tm_ext.tm_sec = tmp->tm_sec; 00252 tm_ext.tm_min = tmp->tm_min; 00253 tm_ext.tm_hour = tmp->tm_hour; 00254 tm_ext.tm_mday = tmp->tm_mday; 00255 tm_ext.tm_mon = tmp->tm_mon; 00256 tm_ext.tm_year = tmp->tm_year; 00257 tm_ext.tm_wday = tmp->tm_wday; 00258 tm_ext.tm_yday = tmp->tm_yday; 00259 tm_ext.tm_isdst = tmp->tm_isdst; 00260 tm_ext.tm_tzo_min = get_tzo_min(); 00261 return &tm_ext; 00262 } 00263 00264 time_t TimeInterface::mktime(struct tm_ex * timeptr) 00265 { 00266 timeptr->tm_tzo_min = get_tzo_min(); 00267 return std::mktime((struct tm *)timeptr); 00268 } 00269 00270 size_t TimeInterface::strftime(char * ptr, size_t maxsize, const char * format, const struct tm_ex * timeptr) 00271 { 00272 return std::strftime(ptr, maxsize, format, (struct tm *)timeptr); 00273 } 00274 00275 double TimeInterface::difftime(time_t end, time_t beginning) 00276 { 00277 return std::difftime(end, beginning); 00278 } 00279 00280 00281 00282 // time zone functions 00283 00284 void TimeInterface::set_time(time_t t, int16_t tzo_min) 00285 { 00286 time_t tval = t - (tzo_min * 60); 00287 rtc_init(); 00288 rtc_write(tval); 00289 LPC_RTC->GPREG1 = tval; 00290 INFO("set_time(%s)", ctime(&tval)); 00291 } 00292 00293 void TimeInterface::set_tzo_min(int16_t tzo_min) 00294 { 00295 uint16_t th; 00296 uint32_t treg; 00297 00298 if (tzo_min >= -720 && tzo_min <= 720) { 00299 th = (uint16_t)(-tzo_min); 00300 treg = (th << 16) | (uint16_t)tzo_min; 00301 LPC_RTC->GPREG0 = treg; 00302 //printf("set_tzo(%d) %d is %08X\r\n", tzo, th, LPC_RTC->GPREG0); 00303 } 00304 } 00305 00306 int16_t TimeInterface::get_tzo_min(void) 00307 { 00308 uint16_t th, tl; 00309 00310 th = LPC_RTC->GPREG0 >> 16; 00311 tl = LPC_RTC->GPREG0; 00312 //printf("get_tzo() is %04X %04X\r\n", th, tl); 00313 if ((uint16_t)(th + tl) == 0) { 00314 return tl; 00315 } else { 00316 return 0; 00317 } 00318 } 00319 00320 time_t TimeInterface::get_timelastset(void) 00321 { 00322 return LPC_RTC->GPREG1; 00323 } 00324 00325 int32_t TimeInterface::get_cal() 00326 { 00327 int32_t calvalue = LPC_RTC->CALIBRATION & 0x3FFFF; 00328 00329 if (calvalue & 0x20000) { 00330 calvalue = -(calvalue & 0x1FFFF); 00331 } 00332 return calvalue; 00333 } 00334 00335 void TimeInterface::set_cal(int32_t calibration) 00336 { 00337 if (calibration) { 00338 if (calibration < 0) { 00339 calibration = (-calibration & 0x1FFFF) | 0x20000; 00340 } 00341 LPC_RTC->CCR = 0x000001; //(LPC_RTC->CCR & 0x0003); // Clear CCALEN to enable it 00342 } else { 00343 LPC_RTC->CCR = 0x000011; //(LPC_RTC->CCR & 0x0003) | 0x0010; // Set CCALEN to disable it 00344 } 00345 LPC_RTC->CALIBRATION = calibration; 00346 } 00347 00348 bool TimeInterface::adjust_sec(int32_t adjustSeconds) 00349 { 00350 time_t lastSet = get_timelastset(); 00351 00352 if (lastSet != 0) { 00353 time_t seconds = time(NULL); // get "now" according to the rtc 00354 int32_t delta = seconds - lastSet; 00355 //int32_t curCal = get_cal(); // calibration might want to leverage the current cal factor. 00356 int32_t calMAX = 131071; 00357 int32_t secPerDay = 86400; 00358 float errSecPerDay; 00359 00360 // Convert the current calibration and the adjustment into 00361 // the new calibration value 00362 // assume it is +10sec and it has been 2days, then the adjustment 00363 // needs to be +5 sec per day, or one adjustment every 1/5th 00364 // of a day, or 1 adjustment every 86400/5 counts. 00365 // delta = now - then (number of elapsed seconds) 00366 if (adjustSeconds != 0 && delta != 0) { 00367 int32_t calFactor; 00368 00369 // Make the clock correct 00370 seconds = seconds + adjustSeconds; 00371 set_time(seconds); 00372 // Compute the calibration factor 00373 errSecPerDay = (float)adjustSeconds / ((float)(delta)/secPerDay); 00374 calFactor = (int32_t)((float)secPerDay/errSecPerDay); 00375 if (abs(calFactor) < calMAX) 00376 set_cal(calFactor); 00377 } 00378 return true; 00379 } else { 00380 return false; 00381 } 00382 } 00383 00384 00385 // ############################################################################# 00386 /* 00387 * Enhancement to use a custom tm_ex struct and the time zone by D. Smart 00388 * %Z 00389 * 00390 * Copyright (c) 1994 Powerdog Industries. All rights reserved. 00391 * 00392 * Redistribution and use in source and binary forms, without 00393 * modification, are permitted provided that the following conditions 00394 * are met: 00395 * 1. Redistributions of source code must retain the above copyright 00396 * notice, this list of conditions and the following disclaimer. 00397 * 2. Redistributions in binary form must reproduce the above copyright 00398 * notice, this list of conditions and the following disclaimer 00399 * in the documentation and/or other materials provided with the 00400 * distribution. 00401 * 3. All advertising materials mentioning features or use of this 00402 * software must display the following acknowledgement: 00403 * This product includes software developed by Powerdog Industries. 00404 * 4. The name of Powerdog Industries may not be used to endorse or 00405 * promote products derived from this software without specific prior 00406 * written permission. 00407 * 00408 * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``AS IS'' AND ANY 00409 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00410 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00411 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE POWERDOG INDUSTRIES BE 00412 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00413 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00414 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 00415 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00416 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 00417 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 00418 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00419 */ 00420 00421 #define asizeof(a) (sizeof (a) / sizeof ((a)[0])) 00422 00423 struct dtconv { 00424 const char *abbrev_month_names[12]; 00425 const char *month_names[12]; 00426 const char *abbrev_weekday_names[7]; 00427 const char *weekday_names[7]; 00428 const char *time_format; 00429 const char *sdate_format; 00430 const char *dtime_format; 00431 const char *am_string; 00432 const char *pm_string; 00433 const char *ldate_format; 00434 const char *zone_names[10]; 00435 int8_t zone_offsets[10]; 00436 }; 00437 00438 static const struct dtconv En_US = { 00439 { 00440 "Jan", "Feb", "Mar", "Apr", "May", "Jun", 00441 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 00442 }, 00443 { 00444 "January", "February", "March", "April", 00445 "May", "June", "July", "August", 00446 "September", "October", "November", "December" 00447 }, 00448 { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }, 00449 { 00450 "Sunday", "Monday", "Tuesday", "Wednesday", 00451 "Thursday", "Friday", "Saturday" 00452 }, 00453 "%H:%M:%S", 00454 "%m/%d/%y", 00455 "%a %b %e %T %Z %Y", 00456 "AM", 00457 "PM", 00458 "%A, %B, %e, %Y", 00459 { "UTC", "EST", "CST", "MST", "PST", "YST", "CAT", "HST", "CET", "EET", }, 00460 { 0, -5, -6, -7, -8, -9, -10, -10, +1, +2, }, 00461 }; 00462 00463 00464 #ifndef isprint 00465 #define in_range(c, lo, up) ((uint8_t)c >= lo && (uint8_t)c <= up) 00466 #define isprint(c) in_range(c, 0x20, 0x7f) 00467 #define isdigit(c) in_range(c, '0', '9') 00468 #define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) 00469 #define islower(c) in_range(c, 'a', 'z') 00470 #define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') 00471 #endif 00472 00473 00474 const char * TimeInterface::strptime(const char *buf, const char *fmt, struct tm_ex *tm) 00475 { 00476 char c; 00477 const char *ptr; 00478 int i, len; 00479 size_t ndx; 00480 bool fSet_wday = false; // so we can notice if the wday was set 00481 00482 ptr = fmt; 00483 while (*ptr != 0) { 00484 if (*buf == 0) 00485 break; 00486 00487 c = *ptr++; 00488 00489 if (c != '%') { 00490 if (isspace(c)) 00491 while (*buf != 0 && isspace(*buf)) 00492 buf++; 00493 else if (c != *buf++) 00494 return 0; 00495 continue; 00496 } 00497 00498 c = *ptr++; 00499 switch (c) { 00500 case 0: 00501 case '%': 00502 if (*buf++ != '%') 00503 return 0; 00504 break; 00505 00506 case 'C': 00507 buf = strptime(buf, En_US.ldate_format, tm); 00508 if (buf == 0) 00509 return 0; 00510 break; 00511 00512 case 'c': 00513 buf = strptime(buf, "%x %X", tm); 00514 if (buf == 0) 00515 return 0; 00516 break; 00517 00518 case 'D': 00519 buf = strptime(buf, "%m/%d/%y", tm); 00520 if (buf == 0) 00521 return 0; 00522 break; 00523 00524 case 'R': 00525 buf = strptime(buf, "%H:%M", tm); 00526 if (buf == 0) 00527 return 0; 00528 break; 00529 00530 case 'r': 00531 buf = strptime(buf, "%I:%M:%S %p", tm); 00532 if (buf == 0) 00533 return 0; 00534 break; 00535 00536 case 'T': 00537 buf = strptime(buf, "%H:%M:%S", tm); 00538 if (buf == 0) 00539 return 0; 00540 break; 00541 00542 case 'X': 00543 buf = strptime(buf, En_US.time_format, tm); 00544 if (buf == 0) 00545 return 0; 00546 break; 00547 00548 case 'x': 00549 buf = strptime(buf, En_US.sdate_format, tm); 00550 if (buf == 0) 00551 return 0; 00552 break; 00553 00554 case 'j': 00555 if (!isdigit(*buf)) 00556 return 0; 00557 00558 for (i = 0; *buf != 0 && isdigit(*buf); buf++) { 00559 i *= 10; 00560 i += *buf - '0'; 00561 } 00562 if (i > 365) 00563 return 0; 00564 00565 tm->tm_yday = i; 00566 break; 00567 00568 case 'M': 00569 case 'S': 00570 if (*buf == 0 || isspace(*buf)) 00571 break; 00572 00573 if (!isdigit(*buf)) 00574 return 0; 00575 00576 for (i = 0; *buf != 0 && isdigit(*buf); buf++) { 00577 i *= 10; 00578 i += *buf - '0'; 00579 } 00580 if (i > 59) 00581 return 0; 00582 00583 if (c == 'M') 00584 tm->tm_min = i; 00585 else 00586 tm->tm_sec = i; 00587 00588 if (*buf != 0 && isspace(*buf)) 00589 while (*ptr != 0 && !isspace(*ptr)) 00590 ptr++; 00591 break; 00592 00593 case 'H': 00594 case 'I': 00595 case 'k': 00596 case 'l': 00597 if (!isdigit(*buf)) 00598 return 0; 00599 00600 for (i = 0; *buf != 0 && isdigit(*buf); buf++) { 00601 i *= 10; 00602 i += *buf - '0'; 00603 } 00604 if (c == 'H' || c == 'k') { 00605 if (i > 23) 00606 return 0; 00607 } else if (i > 11) 00608 return 0; 00609 00610 tm->tm_hour = i; 00611 00612 if (*buf != 0 && isspace(*buf)) 00613 while (*ptr != 0 && !isspace(*ptr)) 00614 ptr++; 00615 break; 00616 00617 case 'p': 00618 len = strlen(En_US.am_string); 00619 if (strncasecmp(buf, En_US.am_string, len) == 0) { 00620 if (tm->tm_hour > 12) 00621 return 0; 00622 if (tm->tm_hour == 12) 00623 tm->tm_hour = 0; 00624 buf += len; 00625 break; 00626 } 00627 00628 len = strlen(En_US.pm_string); 00629 if (strncasecmp(buf, En_US.pm_string, len) == 0) { 00630 if (tm->tm_hour > 12) 00631 return 0; 00632 if (tm->tm_hour != 12) 00633 tm->tm_hour += 12; 00634 buf += len; 00635 break; 00636 } 00637 00638 return 0; 00639 00640 case 'A': 00641 case 'a': 00642 for (ndx = 0; ndx < asizeof(En_US.weekday_names); ndx++) { 00643 len = strlen(En_US.weekday_names[ndx]); 00644 if (strncasecmp(buf, En_US.weekday_names[ndx], len) == 0) 00645 break; 00646 00647 len = strlen(En_US.abbrev_weekday_names[ndx]); 00648 if (strncasecmp(buf, En_US.abbrev_weekday_names[ndx], len) == 0) 00649 break; 00650 } 00651 if (ndx == asizeof(En_US.weekday_names)) 00652 return 0; 00653 fSet_wday = true; 00654 tm->tm_wday = ndx; 00655 buf += len; 00656 break; 00657 00658 case 'd': 00659 case 'e': 00660 if (!isdigit(*buf)) 00661 return 0; 00662 00663 for (i = 0; *buf != 0 && isdigit(*buf); buf++) { 00664 i *= 10; 00665 i += *buf - '0'; 00666 } 00667 if (i > 31) 00668 return 0; 00669 00670 tm->tm_mday = i; 00671 00672 if (*buf != 0 && isspace(*buf)) 00673 while (*ptr != 0 && !isspace(*ptr)) 00674 ptr++; 00675 break; 00676 00677 case 'B': 00678 case 'b': 00679 case 'h': 00680 for (ndx = 0; ndx < asizeof(En_US.month_names); ndx++) { 00681 len = strlen(En_US.month_names[ndx]); 00682 if (strncasecmp(buf, En_US.month_names[ndx], len) == 0) 00683 break; 00684 00685 len = strlen(En_US.abbrev_month_names[ndx]); 00686 if (strncasecmp(buf, En_US.abbrev_month_names[ndx], len) == 0) 00687 break; 00688 } 00689 if (ndx == asizeof(En_US.month_names)) 00690 return 0; 00691 00692 tm->tm_mon = ndx; 00693 buf += len; 00694 break; 00695 00696 case 'm': 00697 if (!isdigit(*buf)) 00698 return 0; 00699 00700 for (i = 0; *buf != 0 && isdigit(*buf); buf++) { 00701 i *= 10; 00702 i += *buf - '0'; 00703 } 00704 if (i < 1 || i > 12) 00705 return 0; 00706 00707 tm->tm_mon = i - 1; 00708 00709 if (*buf != 0 && isspace(*buf)) 00710 while (*ptr != 0 && !isspace(*ptr)) 00711 ptr++; 00712 break; 00713 00714 case 'Y': 00715 case 'y': 00716 if (*buf == 0 || isspace(*buf)) 00717 break; 00718 00719 if (!isdigit(*buf)) 00720 return 0; 00721 00722 for (i = 0; *buf != 0 && isdigit(*buf); buf++) { 00723 i *= 10; 00724 i += *buf - '0'; 00725 } 00726 if (c == 'Y') 00727 i -= 1900; 00728 if (i < 0) 00729 return 0; 00730 00731 tm->tm_year = i; 00732 00733 if (*buf != 0 && isspace(*buf)) 00734 while (*ptr != 0 && !isspace(*ptr)) 00735 ptr++; 00736 break; 00737 case 'Z': 00738 for (ndx = 0; ndx < asizeof(En_US.zone_names); ndx++) { 00739 len = strlen(En_US.zone_names[ndx]); 00740 if (strncasecmp(buf, En_US.zone_names[ndx], len) == 0) 00741 break; 00742 } 00743 if (ndx == asizeof(En_US.zone_names)) 00744 return 0; 00745 tm->tm_tzo_min = En_US.zone_offsets[ndx] * 60; 00746 buf += len; 00747 break; 00748 } 00749 } 00750 if (!fSet_wday) { 00751 if (mktime(tm) == (time_t)-1) 00752 tm->tm_wday = 7; 00753 } 00754 return buf; 00755 }
Generated on Wed Jul 20 2022 15:36:36 by 1.7.2