fix timezone handling

master
leitner 10 years ago
parent ac6979e4af
commit e5865bcc52

@ -1,8 +1,8 @@
#define _GNU_SOURCE
#define __deprecated__
#include "scan.h" #include "scan.h"
#include "byte.h" #include "byte.h"
#include "case.h" #include "case.h"
#define _GNU_SOURCE
#define __deprecated__
#include <time.h> #include <time.h>
#include <stdlib.h> #include <stdlib.h>

@ -15,15 +15,15 @@ size_t scan_iso8601(const char* in,struct timespec* t) {
struct tm x; struct tm x;
const char* c; const char* c;
unsigned long tmp; unsigned long tmp;
size_t i;
if (!(c=in)) return 0; if (!(c=in)) return 0;
if (scan_ulong(c,&tmp)!=4 || c[4]!='-') return 0; c+=5; x.tm_year=(int)(tmp-1900); if ((i=scan_ulong(c,&tmp))<4 || c[i]!='-') return 0; c+=i+1; x.tm_year=(int)(tmp-1900);
if (scan_ulong(c,&tmp)!=2 || c[2]!='-') return 0; c+=3; x.tm_mon=(int)(tmp-1); if (scan_ulong(c,&tmp)!=2 || c[2]!='-') return 0; c+=3; x.tm_mon=(int)(tmp-1);
if (scan_ulong(c,&tmp)!=2 || c[2]!='T') return 0; c+=3; x.tm_mday=(int)tmp; if (scan_ulong(c,&tmp)!=2 || c[2]!='T') return 0; c+=3; x.tm_mday=(int)tmp;
if (scan_ulong(c,&tmp)!=2 || c[2]!=':') return 0; c+=3; x.tm_hour=(int)tmp; if (scan_ulong(c,&tmp)!=2 || c[2]!=':') return 0; c+=3; x.tm_hour=(int)tmp;
if (scan_ulong(c,&tmp)!=2 || c[2]!=':') return 0; c+=3; x.tm_min=(int)tmp; if (scan_ulong(c,&tmp)!=2 || c[2]!=':') return 0; c+=3; x.tm_min=(int)tmp;
if (scan_ulong(c,&tmp)!=2) return 0; c+=2; x.tm_sec=(int)tmp; if (scan_ulong(c,&tmp)!=2) return 0; c+=2; x.tm_sec=(int)tmp;
if (*c=='.') { if (*c=='.') {
size_t i;
++c; ++c;
i=scan_ulong(c,&tmp); i=scan_ulong(c,&tmp);
c+=i; c+=i;
@ -38,7 +38,7 @@ size_t scan_iso8601(const char* in,struct timespec* t) {
} }
} }
x.tm_wday=x.tm_yday=x.tm_isdst=0; x.tm_wday=x.tm_yday=x.tm_isdst=x.tm_gmtoff=0;
#if defined(__dietlibc__) || defined(__GLIBC__) #if defined(__dietlibc__) || defined(__GLIBC__)
t->tv_sec=timegm(&x); t->tv_sec=timegm(&x);
#elif defined(__MINGW32__) #elif defined(__MINGW32__)
@ -61,12 +61,10 @@ size_t scan_iso8601(const char* in,struct timespec* t) {
#endif #endif
if (*c=='+' || *c=='-') { if (*c=='+' || *c=='-') {
int signum = (*c=='+') - (*c=='-'); int signum = (*c=='-') - (*c=='+');
unsigned int val;
++c; ++c;
if (scan_ulong(c,&tmp)!=2 || c[2]!=':') return 0; c+=3; val=tmp*60; if (scan_ulong(c,&tmp)!=4) return 0; c+=4;
if (scan_ulong(c,&tmp)!=2) return 0; c+=2; val+=tmp; t->tv_sec+=signum*60*(int)(tmp/100)*60+(int)(tmp%100);
t->tv_sec+=signum*val;
} else if (*c=='Z') } else if (*c=='Z')
++c; ++c;
else else

@ -9,5 +9,6 @@ int main() {
assert(!strcmp(buf,"2015-05-13T21:17:23Z")); assert(!strcmp(buf,"2015-05-13T21:17:23Z"));
struct timespec t; struct timespec t;
assert(scan_iso8601("2015-05-13T21:17:23Z",&t)==20 && t.tv_sec==1431551843); assert(scan_iso8601("2015-05-13T21:17:23Z",&t)==20 && t.tv_sec==1431551843);
assert(scan_iso8601("2015-05-13T14:17:23-0700",&t)==24 && t.tv_sec==1431551843);
return 0; return 0;
} }

Loading…
Cancel
Save