strtotm.c (1902B)
1 #include <u.h> 2 #include <libc.h> 3 #include <ctype.h> 4 5 static char* 6 skiptext(char *q) 7 { 8 while(*q!='\0' && *q!=' ' && *q!='\t' && *q!='\r' && *q!='\n') 9 q++; 10 return q; 11 } 12 13 static char* 14 skipwhite(char *q) 15 { 16 while(*q==' ' || *q=='\t' || *q=='\r' || *q=='\n') 17 q++; 18 return q; 19 } 20 21 static char* months[] = { 22 "jan", "feb", "mar", "apr", 23 "may", "jun", "jul", "aug", 24 "sep", "oct", "nov", "dec" 25 }; 26 27 static int 28 strcmplwr(char *a, char *b, int n) 29 { 30 char *eb; 31 32 eb = b+n; 33 while(*a && *b && b<eb){ 34 if(tolower(*a) != tolower(*b)) 35 return 1; 36 a++; 37 b++; 38 } 39 if(b==eb) 40 return 0; 41 return *a != *b; 42 } 43 44 int 45 strtotm(char *p, Tm *tmp) 46 { 47 char *q, *r; 48 int j; 49 Tm tm; 50 int delta; 51 52 delta = 0; 53 memset(&tm, 0, sizeof(tm)); 54 tm.mon = -1; 55 tm.hour = -1; 56 tm.min = -1; 57 tm.year = -1; 58 tm.mday = -1; 59 for(p=skipwhite(p); *p; p=skipwhite(q)){ 60 q = skiptext(p); 61 62 /* look for time in hh:mm[:ss] */ 63 if(r = memchr(p, ':', q-p)){ 64 tm.hour = strtol(p, 0, 10); 65 tm.min = strtol(r+1, 0, 10); 66 if(r = memchr(r+1, ':', q-(r+1))) 67 tm.sec = strtol(r+1, 0, 10); 68 else 69 tm.sec = 0; 70 continue; 71 } 72 73 /* look for month */ 74 for(j=0; j<12; j++) 75 if(strcmplwr(p, months[j], 3)==0){ 76 tm.mon = j; 77 break; 78 } 79 80 if(j!=12) 81 continue; 82 83 /* look for time zone [A-Z][A-Z]T */ 84 if(q-p==3 && 'A' <= p[0] && p[0] <= 'Z' 85 && 'A' <= p[1] && p[1] <= 'Z' && p[2] == 'T'){ 86 strecpy(tm.zone, tm.zone+4, p); 87 continue; 88 } 89 90 if(p[0]=='+'||p[0]=='-') 91 if(q-p==5 && strspn(p+1, "0123456789") == 4){ 92 delta = (((p[1]-'0')*10+p[2]-'0')*60+(p[3]-'0')*10+p[4]-'0')*60; 93 if(p[0] == '-') 94 delta = -delta; 95 continue; 96 } 97 if(strspn(p, "0123456789") == q-p){ 98 j = strtol(p, nil, 10); 99 if(1 <= j && j <= 31) 100 tm.mday = j; 101 if(j >= 1900) 102 tm.year = j-1900; 103 } 104 } 105 106 if(tm.mon<0 || tm.year<0 107 || tm.hour<0 || tm.min<0 108 || tm.mday<0) 109 return -1; 110 111 *tmp = *localtime(tm2sec(&tm)-delta); 112 return 0; 113 }