summaryrefslogtreecommitdiff
path: root/src/time/strptime.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/time/strptime.c')
-rw-r--r--src/time/strptime.c59
1 files changed, 58 insertions, 1 deletions
diff --git a/src/time/strptime.c b/src/time/strptime.c
index c54a0d8c..40bb37af 100644
--- a/src/time/strptime.c
+++ b/src/time/strptime.c
@@ -5,6 +5,7 @@
#include <stddef.h>
#include <string.h>
#include <strings.h>
+#include "time_impl.h"
char *strptime(const char *restrict s, const char *restrict f, struct tm *restrict tm)
{
@@ -59,6 +60,22 @@ char *strptime(const char *restrict s, const char *restrict f, struct tm *restri
s = strptime(s, "%m/%d/%y", tm);
if (!s) return 0;
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':
dest = &tm->tm_hour;
min = 0;
@@ -114,6 +131,13 @@ char *strptime(const char *restrict s, const char *restrict f, struct tm *restri
s = strptime(s, "%H:%M", tm);
if (!s) return 0;
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':
dest = &tm->tm_sec;
min = 0;
@@ -125,11 +149,30 @@ char *strptime(const char *restrict s, const char *restrict f, struct tm *restri
break;
case 'U':
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;
min = 0;
range = 54;
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':
dest = &tm->tm_wday;
min = 0;
@@ -154,6 +197,20 @@ char *strptime(const char *restrict s, const char *restrict f, struct tm *restri
adj = 1900;
want_century = 0;
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':
+ i = __tzname_to_isdst(&s);
+ if (i>=0) tm->tm_isdst = i;
+ break;
case '%':
if (*s++ != '%') return 0;
break;