xref: /plan9/sys/src/cmd/upas/fs/strtotm.c (revision 106486e87debb09341599ec7e9df67e8fc46c504)
1 #include <u.h>
2 #include <libc.h>
3 #include <ctype.h>
4 
5 static char*
skiptext(char * q)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*
skipwhite(char * q)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
strcmplwr(char * a,char * b,int n)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
strtotm(char * p,Tm * tmp)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 }
114