1 #define _GNU_SOURCE
2 #define __deprecated__
3 #include "scan.h"
4 #include "byte.h"
5 #include "case.h"
6 #include <time.h>
7 #include <stdlib.h>
8
9 #ifdef sgi
10 extern char** environ;
11 #endif
12
13 /* "2014-05-27T19:22:16Z" */
scan_iso8601(const char * in,struct timespec * t)14 size_t scan_iso8601(const char* in,struct timespec* t) {
15 struct tm x;
16 const char* c;
17 unsigned long tmp;
18 size_t i;
19 if (!(c=in)) return 0;
20 if ((i=scan_ulong(c,&tmp))<4 || c[i]!='-') return 0;
21 c+=i+1; x.tm_year=(int)(tmp-1900);
22 if (scan_ulong(c,&tmp)!=2 || c[2]!='-') return 0;
23 c+=3; x.tm_mon=(int)(tmp-1);
24 if (scan_ulong(c,&tmp)!=2 || c[2]!='T') return 0;
25 c+=3; x.tm_mday=(int)tmp;
26 if (scan_ulong(c,&tmp)!=2 || c[2]!=':') return 0;
27 c+=3; x.tm_hour=(int)tmp;
28 if (scan_ulong(c,&tmp)!=2 || c[2]!=':') return 0;
29 c+=3; x.tm_min=(int)tmp;
30 if (scan_ulong(c,&tmp)!=2) return 0;
31 c+=2; x.tm_sec=(int)tmp;
32 if (*c=='.') {
33 ++c;
34 i=scan_ulong(c,&tmp);
35 c+=i;
36 if (i<1 || i>9)
37 t->tv_nsec=0;
38 else {
39 while (i<9) {
40 ++i;
41 tmp*=10;
42 }
43 t->tv_nsec=tmp;
44 }
45 }
46
47 #ifdef __MINGW32__
48 x.tm_wday=x.tm_yday=x.tm_isdst=0;
49 #else
50 x.tm_wday=x.tm_yday=x.tm_isdst=x.tm_gmtoff=0;
51 #endif
52 #if defined(__dietlibc__) || defined(__GLIBC__)
53 t->tv_sec=timegm(&x);
54 #elif defined(__MINGW32__)
55 t->tv_sec=mktime(&x);
56 #else
57 {
58 #ifdef sgi
59 char** old=environ;
60 char** newenv={0};
61 environ=newenv;
62 t->tv_sec=mktime(&x);
63 environ=old;
64 #else
65 char* old=getenv("TZ");
66 unsetenv("TZ");
67 t->tv_sec=mktime(&x);
68 if (old) setenv("TZ",old,1);
69 #endif
70 }
71 #endif
72
73 if (*c=='+' || *c=='-') {
74 int signum = (*c=='-') - (*c=='+');
75 ++c;
76 if (scan_ulong(c,&tmp)!=4) return 0;
77 c+=4;
78 t->tv_sec+=signum*60*(int)(tmp/100)*60+(int)(tmp%100);
79 } else if (*c=='Z')
80 ++c;
81 else
82 return 0;
83 return (size_t)(c-in);
84 }
85