Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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