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
00047 #include <stdio.h>
00048 #include <string.h>
00049 #include <ctype.h>
00050
00051 #include <pro/rfctime.h>
00052
00053 static char rfc1123_buf[32];
00054 static char *wkdays[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
00055 static char *months[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
00056
00064 static char *skip_spaces(CONST char *str)
00065 {
00066 while (*str == ' ' || *str == '\t')
00067 str++;
00068 return (char *)str;
00069 }
00070
00081 static char *parse_digits(CONST char *str, int *val)
00082 {
00083 *val = 0;
00084 while (isdigit(*str)) {
00085 *val *= 10;
00086 *val += *str++ - '0';
00087 }
00088 return (char *)str;
00089 }
00090
00103 char *TimeParseYear(CONST char *str, int *year)
00104 {
00105 str = parse_digits(str, year);
00106 if (*year < 70) {
00107 *year += 100;
00108 }
00109 else if (*year > 1900) {
00110 *year -= 1900;
00111 }
00112 return (char *)str;
00113 }
00114
00129 char *TimeParseMonth(CONST char *str, int *month)
00130 {
00131 if (*str == 'A') {
00132 if (*++str == 'p' || *str == 'P') {
00133
00134 *month = 3;
00135 }
00136 else {
00137
00138 *month = 7;
00139 }
00140 }
00141 else if (*str == 'D') {
00142
00143 *month = 11;
00144 }
00145 else if (*str == 'F') {
00146
00147 *month = 1;
00148 }
00149 else if (*str == 'J') {
00150 if (*++str == 'a' || *str == 'A') {
00151
00152 *month = 0;
00153 }
00154 else if (*str && (*++str == 'l' || *str == 'L')) {
00155
00156 *month = 6;
00157 }
00158 else {
00159
00160 *month = 5;
00161 }
00162 }
00163 else if (*str == 'M') {
00164 if (*++str == 'a' && (*++str == 'r' || *str == 'R')) {
00165
00166 *month = 2;
00167 }
00168 else {
00169
00170 *month = 4;
00171 }
00172 }
00173 else if (*str == 'N') {
00174
00175 *month = 10;
00176 }
00177 else if (*str == 'O') {
00178
00179 *month = 9;
00180 }
00181 else {
00182
00183 *month = 8;
00184 }
00185 while (isalpha(*str)) {
00186 str++;
00187 }
00188 return (char *)str;
00189 }
00190
00204 char *TimeParseDmy(CONST char *str, int *mday, int *mon, int *year)
00205 {
00206 str = parse_digits(str, mday);
00207 while (*str && !isalpha(*str)) {
00208 str++;
00209 }
00210 str = TimeParseMonth(str, mon);
00211 while (*str && !isdigit(*str)) {
00212 str++;
00213 }
00214 str = TimeParseYear(str, year);
00215
00216 return (char *)str;
00217 }
00218
00231 char *TimeParseHms(CONST char *str, int *hour, int *min, int *sec)
00232 {
00233 str = parse_digits(str, hour);
00234 if (*str == ':') {
00235 str = parse_digits(str + 1, min);
00236 if (*str == ':') {
00237 str = parse_digits(str + 1, sec);
00238 }
00239 else {
00240 *sec = 0;
00241 }
00242 }
00243 else {
00244 *min = 0;
00245 }
00246 return (char *)str;
00247 }
00248
00258 time_t RfcTimeParse(CONST char *str)
00259 {
00260 struct _tm dts = { 0, 0, 0, 1, 0, 0, 0, 0, 0 };
00261
00262
00263 str = skip_spaces(str);
00264
00265
00266 if (isalpha(*str)) {
00267 while (*str && *str != ' ' && *str != '\t')
00268 str++;
00269 str = skip_spaces(str);
00270 }
00271
00272 if (isalpha(*str)) {
00273
00274 str = TimeParseMonth(str, &dts.tm_mon);
00275 str = skip_spaces(str);
00276 str = parse_digits(str, &dts.tm_mday);
00277 str = skip_spaces(str);
00278 str = TimeParseYear(str, &dts.tm_year);
00279 str = skip_spaces(str);
00280 str = TimeParseHms(str, &dts.tm_hour, &dts.tm_min, &dts.tm_sec);
00281 }
00282 else if (*str) {
00283
00284
00285 str = TimeParseDmy(str, &dts.tm_mday, &dts.tm_mon, &dts.tm_year);
00286 str = skip_spaces(str);
00287 str = TimeParseHms(str, &dts.tm_hour, &dts.tm_min, &dts.tm_sec);
00288 }
00289 str = skip_spaces(str);
00290 if (strcmp(str, "GMT")) {
00291 return mktime(&dts);
00292 }
00293 return _mkgmtime(&dts);
00294 }
00295
00303 char *Rfc1123TimeString(struct _tm *tm)
00304 {
00305 sprintf(rfc1123_buf, "%s, %02d %s %04d %02d:%02d:%02d",
00306 wkdays[tm->tm_wday],
00307 tm->tm_mday, months[tm->tm_mon], tm->tm_year + 1900,
00308 tm->tm_hour, tm->tm_min, tm->tm_sec);
00309
00310 return rfc1123_buf;
00311 }