56 #define _ctloc(x) (_CurrentTimeLocale->x)
64 #define LEGAL_ALT(x) { if (alt_format & ~(x)) return NULL; }
66 static int TM_YEAR_BASE = 1900;
67 static char gmt[] = {
"GMT" };
68 static char utc[] = {
"UTC" };
70 static const char *
const nast[5] = {
71 "EST",
"CST",
"MST",
"PST",
"\0\0\0"
73 static const char *
const nadt[5] = {
74 "EDT",
"CDT",
"MDT",
"PDT",
"\0\0\0"
76 static const char *
const am_pm[2] = {
79 static const char *
const day[7] = {
80 "sunday",
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday"
82 static const char *
const abday[7] = {
83 "sun",
"mon",
"tue",
"wed",
"thu",
"fri",
"sat"
85 static const char *
const mon[12] = {
86 "january",
"february",
"march",
"april",
"may",
"june",
"july",
"august",
"september",
"october",
"november",
"december"
88 static const char *
const abmon[12] = {
89 "jan",
"feb",
"mar",
"apr",
"may",
"jun",
"jul",
"aug",
"sep",
"oct",
"nov",
"dec"
92 static const u_char *conv_num(
const unsigned char *,
int *,
unsigned int,
unsigned int);
93 static const u_char *find_string(
const u_char *,
int *,
const char *
const *,
94 const char *
const *,
int);
97 strptime(
const char *buf,
const char *fmt,
struct tm *tm)
100 const unsigned char *bp, *ep;
101 int alt_format, i, split_year = 0, neg = 0, offs;
104 bp = (
const u_char *)buf;
106 while (bp != NULL && (c = *fmt++) !=
'\0') {
122 again:
switch (c = *fmt++) {
154 new_fmt =
"%m/%d/%y";
159 new_fmt =
"%Y-%m-%d";
169 new_fmt =
"%I:%M:S %p";
174 new_fmt =
"%H:%M:%S";
188 bp = (
const u_char *)
strptime((
const char *)bp,
198 bp = find_string(bp, &tm->tm_wday, day, abday, 7);
205 bp = find_string(bp, &tm->tm_mon, mon, abmon, 12);
211 bp = conv_num(bp, &i, 0, 99);
213 i = i * 100 - TM_YEAR_BASE;
215 i += tm->tm_year % 100;
223 bp = conv_num(bp, &tm->tm_mday, 1, 31);
231 bp = conv_num(bp, &tm->tm_hour, 0, 23);
239 bp = conv_num(bp, &tm->tm_hour, 1, 12);
240 if (tm->tm_hour == 12)
247 bp = conv_num(bp, &i, 1, 366);
253 bp = conv_num(bp, &tm->tm_min, 0, 59);
259 bp = conv_num(bp, &i, 1, 12);
265 bp = find_string(bp, &i, am_pm, NULL, 2);
266 if (tm->tm_hour > 11)
268 tm->tm_hour += i * 12;
273 bp = conv_num(bp, &tm->tm_sec, 0, 61);
278 #define TIME_MAX INT64_MAX
285 if (*bp < '0' || *bp >
'9') {
294 }
while (((uint64_t)sse * 10 <=
TIME_MAX) &&
295 rulim && *bp >=
'0' && *bp <=
'9');
297 if (sse < 0 || (uint64_t)sse >
TIME_MAX) {
302 tm = localtime(&sse);
316 bp = conv_num(bp, &i, 0, 53);
321 bp = conv_num(bp, &tm->tm_wday, 0, 6);
326 bp = conv_num(bp, &i, 1, 7);
334 bp = conv_num(bp, &i, 0, 99);
342 while (isdigit(*bp));
346 bp = conv_num(bp, &i, 0, 53);
351 bp = conv_num(bp, &i, 0, 9999);
352 tm->tm_year = i - TM_YEAR_BASE;
358 bp = conv_num(bp, &i, 0, 99);
362 i += (tm->tm_year / 100) * 100;
366 i = i + 2000 - TM_YEAR_BASE;
368 i = i + 1900 - TM_YEAR_BASE;
375 if (strncasecmp((
const char *)bp, gmt, 3) == 0
376 || strncasecmp((
const char *)bp, utc, 3) == 0) {
386 ep = find_string(bp, &i,
387 (
const char *
const *)tzname,
392 tm->TM_GMTOFF = -(timezone);
395 tm->TM_ZONE = tzname[i];
449 ep = find_string(bp, &i, nast, NULL, 4);
452 tm->TM_GMTOFF = -5 - i;
455 tm->TM_ZONE = __UNCONST(nast[i]);
460 ep = find_string(bp, &i, nadt, NULL, 4);
464 tm->TM_GMTOFF = -4 - i;
467 tm->TM_ZONE = __UNCONST(nadt[i]);
473 if ((*bp >=
'A' && *bp <=
'I') ||
474 (*bp >=
'L' && *bp <=
'Y')) {
477 if (*bp >=
'A' && *bp <=
'I')
479 (
'A' - 1) - (
int)*bp;
480 else if (*bp >=
'L' && *bp <=
'M')
481 tm->TM_GMTOFF =
'A' - (int)*bp;
482 else if (*bp >=
'N' && *bp <=
'Y')
483 tm->TM_GMTOFF = (int)*bp -
'M';
494 for (i = 0; i < 4; ) {
496 offs = offs * 10 + (*bp++ -
'0');
500 if (i == 2 && *bp ==
':') {
515 offs = (offs / 100) * 100 + (i * 50) / 30;
524 tm->TM_GMTOFF = offs;
551 static const u_char *
552 conv_num(
const unsigned char *buf,
int *dest,
unsigned int llim,
unsigned int ulim)
554 unsigned int result = 0;
558 unsigned int rulim = ulim;
561 if (ch < '0' || ch >
'9')
569 }
while ((result * 10 <= ulim) && rulim && ch >=
'0' && ch <=
'9');
571 if (result < llim || result > ulim)
578 static const u_char *
579 find_string(
const u_char *bp,
int *tgt,
const char *
const *n1,
580 const char *
const *n2,
int c)
586 for (; n1 != NULL; n1 = n2, n2 = NULL) {
587 for (i = 0; i < c; i++, n1++) {
589 if (strncasecmp(*n1, (
const char *)bp,
len) == 0) {