Allow the user to specify a time in the format yyyy-mm-ddThh:mm while * also allowing abbreviated data. For instance, if the time is omitted, * it defaults to midnight. If the date is omitted, it defaults to the * next possible date in the future with the specified time. Even the * year or year-month can be omitted, again defaulting to the next date * in the future that matches the specifi
| 1165 | * in the future that matches the specified information. A 2-digit year |
| 1166 | * is also OK, as is using '/' instead of '-'. */ |
| 1167 | static time_t parse_time(const char *arg) |
| 1168 | { |
| 1169 | const char *cp; |
| 1170 | time_t val, now = time(NULL); |
| 1171 | struct tm t, tmp, *today = localtime_r(&now, &tmp); |
| 1172 | int in_date, old_mday, n; |
| 1173 | |
| 1174 | memset(&t, 0, sizeof t); |
| 1175 | t.tm_year = t.tm_mon = t.tm_mday = -1; |
| 1176 | t.tm_hour = t.tm_min = t.tm_isdst = -1; |
| 1177 | cp = arg; |
| 1178 | if (*cp == 'T' || *cp == 't' || *cp == ':') { |
| 1179 | in_date = *cp == ':' ? 0 : -1; |
| 1180 | cp++; |
| 1181 | } else |
| 1182 | in_date = 1; |
| 1183 | for ( ; ; cp++) { |
| 1184 | if (!isDigit(cp)) |
| 1185 | return (time_t)-1; |
| 1186 | n = 0; |
| 1187 | do { |
| 1188 | n = n * 10 + *cp++ - '0'; |
| 1189 | } while (isDigit(cp)); |
| 1190 | if (*cp == ':') |
| 1191 | in_date = 0; |
| 1192 | if (in_date > 0) { |
| 1193 | if (t.tm_year != -1) |
| 1194 | return (time_t)-1; |
| 1195 | t.tm_year = t.tm_mon; |
| 1196 | t.tm_mon = t.tm_mday; |
| 1197 | t.tm_mday = n; |
| 1198 | if (!*cp) |
| 1199 | break; |
| 1200 | if (*cp == 'T' || *cp == 't') { |
| 1201 | if (!cp[1]) |
| 1202 | break; |
| 1203 | in_date = -1; |
| 1204 | } else if (*cp != '-' && *cp != '/') |
| 1205 | return (time_t)-1; |
| 1206 | continue; |
| 1207 | } |
| 1208 | if (t.tm_hour != -1) |
| 1209 | return (time_t)-1; |
| 1210 | t.tm_hour = t.tm_min; |
| 1211 | t.tm_min = n; |
| 1212 | if (!*cp) { |
| 1213 | if (in_date < 0) |
| 1214 | return (time_t)-1; |
| 1215 | break; |
| 1216 | } |
| 1217 | if (*cp != ':') |
| 1218 | return (time_t)-1; |
| 1219 | in_date = 0; |
| 1220 | } |
| 1221 | |
| 1222 | in_date = 0; |
| 1223 | if (t.tm_year < 0) { |
| 1224 | t.tm_year = today->tm_year; |
no test coverage detected