2002-12-11 02:05:12 +08:00
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#define NGX_ERROR -1
|
|
|
|
|
|
|
|
static int mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
|
|
|
|
|
|
|
time_t ngx_http_parse_time(char *value, size_t len)
|
2002-12-11 02:05:12 +08:00
|
|
|
{
|
2002-12-12 00:57:54 +08:00
|
|
|
char *p, *end;
|
|
|
|
int day, month, year, hour, min, sec;
|
2002-12-11 02:05:12 +08:00
|
|
|
enum {
|
2002-12-12 00:57:54 +08:00
|
|
|
no = 0,
|
|
|
|
rfc822, /* Tue 10 Nov 2002 23:50:13 */
|
|
|
|
rfc850, /* Tuesday, 10-Dec-02 23:50:13 */
|
|
|
|
isoc /* Tue Dec 10 23:50:13 2002 */
|
|
|
|
} fmt;
|
2002-12-11 02:05:12 +08:00
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
end = value + len;
|
2002-12-11 02:05:12 +08:00
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
for (p = value; p < end; p++) {
|
|
|
|
if (*p == ',')
|
|
|
|
break;
|
2002-12-11 02:05:12 +08:00
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
if (*p == ' ') {
|
|
|
|
fmt = isoc;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2002-12-11 02:05:12 +08:00
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
for (p++; p < end; p++)
|
|
|
|
if (*p != ' ')
|
2002-12-11 02:05:12 +08:00
|
|
|
break;
|
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
if (end - p < 18)
|
|
|
|
return NGX_ERROR;
|
2002-12-11 02:05:12 +08:00
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
if (fmt != isoc) {
|
|
|
|
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9')
|
|
|
|
return NGX_ERROR;
|
2002-12-11 02:05:12 +08:00
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
day = (*p - '0') * 10 + *(p + 1) - '0';
|
|
|
|
p += 2;
|
2002-12-11 02:05:12 +08:00
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
if (*p == ' ') {
|
|
|
|
if (end - p < 18)
|
|
|
|
return NGX_ERROR;
|
|
|
|
fmt = rfc822;
|
|
|
|
|
|
|
|
} else if (*p == '-') {
|
|
|
|
fmt = rfc850;
|
|
|
|
|
|
|
|
} else {
|
2002-12-11 02:05:12 +08:00
|
|
|
return NGX_ERROR;
|
2002-12-12 00:57:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (*p) {
|
|
|
|
|
|
|
|
case 'J':
|
|
|
|
month = *(p + 1) == 'a' ? 0 : *(p + 2) == 'n' ? 5 : 6;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'F':
|
|
|
|
month = 1;
|
|
|
|
break;
|
2002-12-11 02:05:12 +08:00
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
case 'M':
|
|
|
|
month = *(p + 2) == 'r' ? 2 : 4;
|
|
|
|
break;
|
2002-12-11 02:05:12 +08:00
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
case 'A':
|
|
|
|
month = *(p + 1) == 'p' ? 3 : 7;
|
|
|
|
break;
|
2002-12-11 02:05:12 +08:00
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
case 'S':
|
|
|
|
month = 8;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'O':
|
|
|
|
month = 9;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'N':
|
|
|
|
month = 10;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'D':
|
|
|
|
month = 11;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
p += 3;
|
|
|
|
|
|
|
|
if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-'))
|
|
|
|
return NGX_ERROR;
|
|
|
|
|
|
|
|
p++;
|
|
|
|
|
|
|
|
if (fmt == rfc822) {
|
|
|
|
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9'
|
|
|
|
|| *(p + 2) < '0' || *(p + 2) > '9'
|
|
|
|
|| *(p + 3) < '0' || *(p + 3) > '9')
|
2002-12-11 02:05:12 +08:00
|
|
|
return NGX_ERROR;
|
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
|
|
|
|
+ (*(p + 2) - '0') * 10 + *(p + 3) - '0';
|
|
|
|
p += 4;
|
2002-12-11 02:05:12 +08:00
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
} else if (fmt == rfc850) {
|
|
|
|
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9')
|
|
|
|
return NGX_ERROR;
|
|
|
|
|
|
|
|
year = (*p - '0') * 10 + *(p + 1) - '0';
|
|
|
|
year += (year < 70) ? 2000 : 1900;
|
|
|
|
p += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fmt == isoc) {
|
|
|
|
if (*p == ' ')
|
|
|
|
p++;
|
2002-12-11 02:05:12 +08:00
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
if (*p < '0' || *p > '9')
|
|
|
|
return NGX_ERROR;
|
|
|
|
|
|
|
|
day = *p++ - '0';
|
2002-12-11 02:05:12 +08:00
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
if (*p != ' ') {
|
|
|
|
if (*p < '0' || *p > '9')
|
|
|
|
return NGX_ERROR;
|
2002-12-11 02:05:12 +08:00
|
|
|
|
2002-12-12 00:57:54 +08:00
|
|
|
day = day * 10 + *p++ - '0';
|
2002-12-11 02:05:12 +08:00
|
|
|
}
|
2002-12-12 00:57:54 +08:00
|
|
|
|
|
|
|
if (end - p < 14)
|
|
|
|
return NGX_ERROR;
|
2002-12-11 02:05:12 +08:00
|
|
|
}
|
2002-12-12 00:57:54 +08:00
|
|
|
|
|
|
|
if (*p++ != ' ')
|
|
|
|
return NGX_ERROR;
|
|
|
|
|
|
|
|
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9')
|
|
|
|
return NGX_ERROR;
|
|
|
|
|
|
|
|
hour = (*p - '0') * 10 + *(p + 1) - '0';
|
|
|
|
p += 2;
|
|
|
|
|
|
|
|
if (*p++ != ':')
|
|
|
|
return NGX_ERROR;
|
|
|
|
|
|
|
|
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9')
|
|
|
|
return NGX_ERROR;
|
|
|
|
|
|
|
|
min = (*p - '0') * 10 + *(p + 1) - '0';
|
|
|
|
p += 2;
|
|
|
|
|
|
|
|
if (*p++ != ':')
|
|
|
|
return NGX_ERROR;
|
|
|
|
|
|
|
|
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9')
|
|
|
|
return NGX_ERROR;
|
|
|
|
|
|
|
|
sec = (*p - '0') * 10 + *(p + 1) - '0';
|
|
|
|
|
|
|
|
if (fmt == isoc) {
|
|
|
|
p += 2;
|
|
|
|
|
|
|
|
if (*p++ != ' ')
|
|
|
|
return NGX_ERROR;
|
|
|
|
|
|
|
|
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9'
|
|
|
|
|| *(p + 2) < '0' || *(p + 2) > '9'
|
|
|
|
|| *(p + 3) < '0' || *(p + 3) > '9')
|
|
|
|
return NGX_ERROR;
|
|
|
|
|
|
|
|
year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
|
|
|
|
+ (*(p + 2) - '0') * 10 + *(p + 3) - '0';
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("%d.%d.%d %d:%d:%d\n", day, month + 1, year, hour, min, sec);
|
|
|
|
|
|
|
|
if (hour > 23 || min > 60 || sec > 60)
|
|
|
|
return NGX_ERROR;
|
|
|
|
|
|
|
|
if (day == 29 && month == 1) {
|
|
|
|
if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0))
|
|
|
|
return NGX_ERROR;
|
|
|
|
|
|
|
|
} else if (day > mday[month])
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sizeof(time_t) <= 4 && year >= 2038)
|
|
|
|
return NGX_ERROR;
|
|
|
|
|
|
|
|
if (--month <= 0) {
|
|
|
|
month += 12;
|
|
|
|
year -= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return year / 4 - year / 100 + year / 400
|
|
|
|
+ 367 * month / 12 + day + year * 365 - 719499;
|
|
|
|
}
|
|
|
|
|
|
|
|
char zero[] = "Sun, 01 Jan 1970 08:49:30";
|
|
|
|
char one[] = "Sunday, 11-Dec-02 08:49:30";
|
|
|
|
char two[] = "Sun Mar 1 08:49:37 2000";
|
|
|
|
char thr[] = "Sun Dec 11 08:49:37 2002";
|
|
|
|
|
|
|
|
main()
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = ngx_http_parse_time(zero, sizeof(zero) - 1);
|
|
|
|
printf("rc: %d\n", rc);
|
|
|
|
|
|
|
|
rc = ngx_http_parse_time(one, sizeof(one) - 1);
|
|
|
|
printf("rc: %d\n", rc);
|
|
|
|
|
|
|
|
rc = ngx_http_parse_time(two, sizeof(two) - 1);
|
|
|
|
printf("rc: %d\n", rc);
|
|
|
|
|
|
|
|
rc = ngx_http_parse_time(thr, sizeof(thr) - 1);
|
|
|
|
printf("rc: %d\n", rc);
|
2002-12-11 02:05:12 +08:00
|
|
|
}
|