ref: c06e464ec45dd5880850fa60c850498861c514d3
dir: /sys/src/cmd/upas/fs/strtotm.c/
#include <u.h> #include <libc.h> #include <ctype.h> static char* skiptext(char *q) { while(*q!='\0' && *q!=' ' && *q!='\t' && *q!='\r' && *q!='\n') q++; return q; } static char* skipwhite(char *q) { while(*q==' ' || *q=='\t' || *q=='\r' || *q=='\n') q++; return q; } static char* months[] = { "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" }; static int strcmplwr(char *a, char *b, int n) { char *eb; eb = b+n; while(*a && *b && b<eb){ if(tolower(*a) != tolower(*b)) return 1; a++; b++; } if(b==eb) return 0; return *a != *b; } int strtotm(char *p, Tm *tmp) { char *q, *r; int j; Tm tm; int delta; delta = 0; memset(&tm, 0, sizeof(tm)); tm.mon = -1; tm.hour = -1; tm.min = -1; tm.year = -1; tm.mday = -1; for(p=skipwhite(p); *p; p=skipwhite(q)){ q = skiptext(p); /* look for time in hh:mm[:ss] */ if(r = memchr(p, ':', q-p)){ tm.hour = strtol(p, 0, 10); tm.min = strtol(r+1, 0, 10); if(r = memchr(r+1, ':', q-(r+1))) tm.sec = strtol(r+1, 0, 10); else tm.sec = 0; continue; } /* look for month */ for(j=0; j<12; j++) if(strcmplwr(p, months[j], 3)==0){ tm.mon = j; break; } if(j!=12) continue; /* look for time zone [A-Z][A-Z]T */ if(q-p==3 && 'A' <= p[0] && p[0] <= 'Z' && 'A' <= p[1] && p[1] <= 'Z' && p[2] == 'T'){ strecpy(tm.zone, tm.zone+4, p); continue; } if(p[0]=='+'||p[0]=='-') if(q-p==5 && strspn(p+1, "0123456789") == 4){ delta = (((p[1]-'0')*10+p[2]-'0')*60+(p[3]-'0')*10+p[4]-'0')*60; if(p[0] == '-') delta = -delta; continue; } if(strspn(p, "0123456789") == q-p){ j = strtol(p, nil, 10); if(1 <= j && j <= 31) tm.mday = j; if(j >= 1900) tm.year = j-1900; } } if(tm.mon<0 || tm.year<0 || tm.hour<0 || tm.min<0 || tm.mday<0) return -1; *tmp = *localtime(tm2sec(&tm)-delta); return 0; }