00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00050 #include <stdio.h>
00051 #include <string.h>
00052 #include <ctype.h>
00053
00054 #include <pro/rfctime.h>
00055
00056 static char rfc1123_buf[32];
00057 static char *wkdays[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
00058 static char *months[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
00059
00067 static char *skip_spaces(CONST char *str)
00068 {
00069 while (*str == ' ' || *str == '\t')
00070 str++;
00071 return (char *)str;
00072 }
00073
00084 static char *parse_digits(CONST char *str, int *val)
00085 {
00086 *val = 0;
00087 while (isdigit(*str)) {
00088 *val *= 10;
00089 *val += *str++ - '0';
00090 }
00091 return (char *)str;
00092 }
00093
00106 char *TimeParseYear(CONST char *str, int *year)
00107 {
00108 str = parse_digits(str, year);
00109 if (*year < 70) {
00110 *year += 100;
00111 }
00112 else if (*year > 1900) {
00113 *year -= 1900;
00114 }
00115 return (char *)str;
00116 }
00117
00132 char *TimeParseMonth(CONST char *str, int *month)
00133 {
00134 if (*str == 'A') {
00135 if (*++str == 'p' || *str == 'P') {
00136
00137 *month = 3;
00138 }
00139 else {
00140
00141 *month = 7;
00142 }
00143 }
00144 else if (*str == 'D') {
00145
00146 *month = 11;
00147 }
00148 else if (*str == 'F') {
00149
00150 *month = 1;
00151 }
00152 else if (*str == 'J') {
00153 if (*++str == 'a' || *str == 'A') {
00154
00155 *month = 0;
00156 }
00157 else if (*str && (*++str == 'l' || *str == 'L')) {
00158
00159 *month = 6;
00160 }
00161 else {
00162
00163 *month = 5;
00164 }
00165 }
00166 else if (*str == 'M') {
00167 if (*++str == 'a' && (*++str == 'r' || *str == 'R')) {
00168
00169 *month = 2;
00170 }
00171 else {
00172
00173 *month = 4;
00174 }
00175 }
00176 else if (*str == 'N') {
00177
00178 *month = 10;
00179 }
00180 else if (*str == 'O') {
00181
00182 *month = 9;
00183 }
00184 else {
00185
00186 *month = 8;
00187 }
00188 while (isalpha(*str)) {
00189 str++;
00190 }
00191 return (char *)str;
00192 }
00193
00207 char *TimeParseDmy(CONST char *str, int *mday, int *mon, int *year)
00208 {
00209 str = parse_digits(str, mday);
00210 while (*str && !isalpha(*str)) {
00211 str++;
00212 }
00213 str = TimeParseMonth(str, mon);
00214 while (*str && !isdigit(*str)) {
00215 str++;
00216 }
00217 str = TimeParseYear(str, year);
00218
00219 return (char *)str;
00220 }
00221
00234 char *TimeParseHms(CONST char *str, int *hour, int *min, int *sec)
00235 {
00236 str = parse_digits(str, hour);
00237 if (*str == ':') {
00238 str = parse_digits(str + 1, min);
00239 if (*str == ':') {
00240 str = parse_digits(str + 1, sec);
00241 }
00242 else {
00243 *sec = 0;
00244 }
00245 }
00246 else {
00247 *min = 0;
00248 }
00249 return (char *)str;
00250 }
00251
00261 time_t RfcTimeParse(CONST char *str)
00262 {
00263 struct _tm dts = { 0, 0, 0, 1, 0, 0, 0, 0, 0 };
00264
00265
00266 str = skip_spaces(str);
00267
00268
00269 if (isalpha(*str)) {
00270 while (*str && *str != ' ' && *str != '\t')
00271 str++;
00272 str = skip_spaces(str);
00273 }
00274
00275 if (isalpha(*str)) {
00276
00277 str = TimeParseMonth(str, &dts.tm_mon);
00278 str = skip_spaces(str);
00279 str = parse_digits(str, &dts.tm_mday);
00280 str = skip_spaces(str);
00281 str = TimeParseYear(str, &dts.tm_year);
00282 str = skip_spaces(str);
00283 str = TimeParseHms(str, &dts.tm_hour, &dts.tm_min, &dts.tm_sec);
00284 }
00285 else if (*str) {
00286
00287
00288 str = TimeParseDmy(str, &dts.tm_mday, &dts.tm_mon, &dts.tm_year);
00289 str = skip_spaces(str);
00290 str = TimeParseHms(str, &dts.tm_hour, &dts.tm_min, &dts.tm_sec);
00291 }
00292 str = skip_spaces(str);
00293 if (strcmp(str, "GMT") == 0) {
00294 return mktime(&dts);
00295 }
00296 return _mkgmtime(&dts);
00297 }
00298
00306 char *Rfc1123TimeString(struct _tm *tm)
00307 {
00308 sprintf(rfc1123_buf, "%s, %02d %s %04d %02d:%02d:%02d",
00309 wkdays[tm->tm_wday],
00310 tm->tm_mday, months[tm->tm_mon], tm->tm_year + 1900,
00311 tm->tm_hour, tm->tm_min, tm->tm_sec);
00312
00313 return rfc1123_buf;
00314 }