|
@@ -59,6 +59,22 @@ char *strptime(const char *restrict s, const char *restrict f, struct tm *restri
|
|
s = strptime(s, "%m/%d/%y", tm);
|
|
s = strptime(s, "%m/%d/%y", tm);
|
|
if (!s) return 0;
|
|
if (!s) return 0;
|
|
break;
|
|
break;
|
|
|
|
+ case 'F':
|
|
|
|
+ /* Use temp buffer to implement the odd requirement
|
|
|
|
+ * that entire field be width-limited but the year
|
|
|
|
+ * subfield not itself be limited. */
|
|
|
|
+ i = 0;
|
|
|
|
+ char tmp[20];
|
|
|
|
+ if (*s == '-' || *s == '+') tmp[i++] = *s++;
|
|
|
|
+ while (*s=='0' && isdigit(s[1])) s++;
|
|
|
|
+ for (; *s && i<(size_t)w && i+1<sizeof tmp; i++) {
|
|
|
|
+ tmp[i] = *s++;
|
|
|
|
+ }
|
|
|
|
+ tmp[i] = 0;
|
|
|
|
+ char *p = strptime(tmp, "%12Y-%m-%d", tm);
|
|
|
|
+ if (!p) return 0;
|
|
|
|
+ s -= tmp+i-p;
|
|
|
|
+ break;
|
|
case 'H':
|
|
case 'H':
|
|
dest = &tm->tm_hour;
|
|
dest = &tm->tm_hour;
|
|
min = 0;
|
|
min = 0;
|
|
@@ -114,6 +130,13 @@ char *strptime(const char *restrict s, const char *restrict f, struct tm *restri
|
|
s = strptime(s, "%H:%M", tm);
|
|
s = strptime(s, "%H:%M", tm);
|
|
if (!s) return 0;
|
|
if (!s) return 0;
|
|
break;
|
|
break;
|
|
|
|
+ case 's':
|
|
|
|
+ /* Parse only. Effect on tm is unspecified
|
|
|
|
+ * and presently no effect is implemented.. */
|
|
|
|
+ if (*s == '-') s++;
|
|
|
|
+ if (!isdigit(*s)) return 0;
|
|
|
|
+ while (isdigit(*s)) s++;
|
|
|
|
+ break;
|
|
case 'S':
|
|
case 'S':
|
|
dest = &tm->tm_sec;
|
|
dest = &tm->tm_sec;
|
|
min = 0;
|
|
min = 0;
|
|
@@ -125,11 +148,30 @@ char *strptime(const char *restrict s, const char *restrict f, struct tm *restri
|
|
break;
|
|
break;
|
|
case 'U':
|
|
case 'U':
|
|
case 'W':
|
|
case 'W':
|
|
- /* Throw away result, for now. (FIXME?) */
|
|
|
|
|
|
+ /* Throw away result of %U, %V, %W, %g, and %G. Effect
|
|
|
|
+ * is unspecified and there is no clear right choice. */
|
|
dest = &dummy;
|
|
dest = &dummy;
|
|
min = 0;
|
|
min = 0;
|
|
range = 54;
|
|
range = 54;
|
|
goto numeric_range;
|
|
goto numeric_range;
|
|
|
|
+ case 'V':
|
|
|
|
+ dest = &dummy;
|
|
|
|
+ min = 1;
|
|
|
|
+ range = 53;
|
|
|
|
+ goto numeric_range;
|
|
|
|
+ case 'g':
|
|
|
|
+ dest = &dummy;
|
|
|
|
+ w = 2;
|
|
|
|
+ goto numeric_digits;
|
|
|
|
+ case 'G':
|
|
|
|
+ dest = &dummy;
|
|
|
|
+ if (w<0) w=4;
|
|
|
|
+ goto numeric_digits;
|
|
|
|
+ case 'u':
|
|
|
|
+ dest = &tm->tm_wday;
|
|
|
|
+ min = 1;
|
|
|
|
+ range = 7;
|
|
|
|
+ goto numeric_range;
|
|
case 'w':
|
|
case 'w':
|
|
dest = &tm->tm_wday;
|
|
dest = &tm->tm_wday;
|
|
min = 0;
|
|
min = 0;
|
|
@@ -154,6 +196,28 @@ char *strptime(const char *restrict s, const char *restrict f, struct tm *restri
|
|
adj = 1900;
|
|
adj = 1900;
|
|
want_century = 0;
|
|
want_century = 0;
|
|
goto numeric_digits;
|
|
goto numeric_digits;
|
|
|
|
+ case 'z':
|
|
|
|
+ if (*s == '+') neg = 0;
|
|
|
|
+ else if (*s == '-') neg = 1;
|
|
|
|
+ else return 0;
|
|
|
|
+ for (i=0; i<4; i++) if (!isdigit(s[1+i])) return 0;
|
|
|
|
+ tm->__tm_gmtoff = (s[1]-'0')*36000+(s[2]-'0')*3600
|
|
|
|
+ + (s[3]-'0')*600 + (s[4]-'0')*60;
|
|
|
|
+ if (neg) tm->__tm_gmtoff = -tm->__tm_gmtoff;
|
|
|
|
+ s += 5;
|
|
|
|
+ break;
|
|
|
|
+ case 'Z':
|
|
|
|
+ if (!strncmp(s, tzname[0], len = strlen(tzname[0]))) {
|
|
|
|
+ tm->tm_isdst = 0;
|
|
|
|
+ s += len;
|
|
|
|
+ } else if (!strncmp(s, tzname[1], len=strlen(tzname[1]))) {
|
|
|
|
+ tm->tm_isdst = 1;
|
|
|
|
+ s += len;
|
|
|
|
+ } else {
|
|
|
|
+ /* FIXME: is this supposed to be an error? */
|
|
|
|
+ while ((*s|32)-'a' <= 'z'-'a') s++;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
case '%':
|
|
case '%':
|
|
if (*s++ != '%') return 0;
|
|
if (*s++ != '%') return 0;
|
|
break;
|
|
break;
|