This source file includes following definitions.
- year
- posix_time_parse
- posixtime
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <config.h>
22
23 #include "posixtm.h"
24
25 #include "c-ctype.h"
26 #include "idx.h"
27 #include "intprops.h"
28 #include "verify.h"
29
30 #include <string.h>
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 static bool
50 year (struct tm *tm, const int *digit_pair, idx_t n, unsigned int syntax_bits)
51 {
52 switch (n)
53 {
54 case 1:
55 tm->tm_year = *digit_pair;
56
57
58
59 if (digit_pair[0] <= 68)
60 {
61 if (syntax_bits & PDS_PRE_2000)
62 return false;
63 tm->tm_year += 100;
64 }
65 break;
66
67 case 2:
68 if (! (syntax_bits & PDS_CENTURY))
69 return false;
70 tm->tm_year = digit_pair[0] * 100 + digit_pair[1] - 1900;
71 break;
72
73 case 0:
74 {
75
76 time_t now = time (NULL);
77 struct tm *tmp = localtime (&now);
78 if (! tmp)
79 return false;
80 tm->tm_year = tmp->tm_year;
81 }
82 break;
83
84 default:
85 assume (false);
86 }
87
88 return true;
89 }
90
91 static bool
92 posix_time_parse (struct tm *tm, const char *s, unsigned int syntax_bits)
93 {
94 const char *dot = NULL;
95 int pair[6];
96
97 idx_t s_len = strlen (s);
98 idx_t len = s_len;
99
100 if (syntax_bits & PDS_SECONDS)
101 {
102 dot = strchr (s, '.');
103 if (dot)
104 {
105 len = dot - s;
106 if (s_len - len != 3)
107 return false;
108 }
109 }
110
111 if (! (8 <= len && len <= 12 && len % 2 == 0))
112 return false;
113
114 for (idx_t i = 0; i < len; i++)
115 if (!c_isdigit (s[i]))
116 return false;
117
118 len /= 2;
119 for (idx_t i = 0; i < len; i++)
120 pair[i] = 10 * (s[2*i] - '0') + s[2*i + 1] - '0';
121
122 int *p = pair;
123 if (! (syntax_bits & PDS_TRAILING_YEAR))
124 {
125 if (! year (tm, p, len - 4, syntax_bits))
126 return false;
127 p += len - 4;
128 len = 4;
129 }
130
131
132 tm->tm_mon = *p++ - 1;
133 tm->tm_mday = *p++;
134 tm->tm_hour = *p++;
135 tm->tm_min = *p++;
136 len -= 4;
137
138
139 if (syntax_bits & PDS_TRAILING_YEAR)
140 {
141 if (! year (tm, p, len, syntax_bits))
142 return false;
143 }
144
145
146 if (!dot)
147 tm->tm_sec = 0;
148 else if (c_isdigit (dot[1]) && c_isdigit (dot[2]))
149 tm->tm_sec = 10 * (dot[1] - '0') + dot[2] - '0';
150 else
151 return false;
152
153 return true;
154 }
155
156
157
158 bool
159 posixtime (time_t *p, const char *s, unsigned int syntax_bits)
160 {
161 struct tm tm0;
162 bool leapsec = false;
163
164 if (! posix_time_parse (&tm0, s, syntax_bits))
165 return false;
166
167 while (true)
168 {
169 struct tm tm1;
170 tm1.tm_sec = tm0.tm_sec;
171 tm1.tm_min = tm0.tm_min;
172 tm1.tm_hour = tm0.tm_hour;
173 tm1.tm_mday = tm0.tm_mday;
174 tm1.tm_mon = tm0.tm_mon;
175 tm1.tm_year = tm0.tm_year;
176 tm1.tm_wday = -1;
177 tm1.tm_isdst = -1;
178 time_t t = mktime (&tm1);
179
180 if (tm1.tm_wday < 0)
181 return false;
182
183
184
185
186
187 if (! ((tm0.tm_year ^ tm1.tm_year)
188 | (tm0.tm_mon ^ tm1.tm_mon)
189 | (tm0.tm_mday ^ tm1.tm_mday)
190 | (tm0.tm_hour ^ tm1.tm_hour)
191 | (tm0.tm_min ^ tm1.tm_min)
192 | (tm0.tm_sec ^ tm1.tm_sec)))
193 {
194 if (INT_ADD_WRAPV (t, leapsec, &t))
195 return false;
196 *p = t;
197 return true;
198 }
199
200
201 if (tm0.tm_sec != 60)
202 return false;
203
204
205 tm0.tm_sec = 59;
206 leapsec = true;
207 }
208 }