/* $Id: date.c 11 2007-08-27 17:45:05Z vol $ */ #include #include #include #include #include "date.h" #include "rfc2822.h" static const char *days[] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", NULL }; static const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL }; /* Parse an RFC2822 or obsolete date and convert to tm structure. Does not take DST into account Wed, 11 Jul 2007 11:51:28 -0500 Wed, 11 Jul 2007 11:51:28 EST 5 Jul 2006 14:29:32 -0000 */ int date_parse(struct tm *tm, char *str) { int i = 0; char *h = NULL, *t = NULL, c = 0, utc[3] = { 0 }; if ((str == NULL) || (!(*str))) return 0; while(rfc2822_is_wsp(*str)) str++; h = str; t = rfc2822_next_token(str, ',', "\t "); if (t == NULL) return 0; /* Day of the week is optional */ if (*t == ',') { *t++ = '\0'; for (i = 0; days[i]; i++) { if (!(strcasecmp(days[i], h))) break; } if (days[i] == NULL) return 0; tm->tm_wday = (i + 1); // printf("Day of the week: %d\n", tm->tm_wday); while(rfc2822_is_wsp(*t)) t++; h = t; } /* Day of the month */ t = rfc2822_next_token(t, ' ', "\t"); if (t == NULL) return 0; *t++ = '\0'; i = atoi(h); if (i == 0) return 0; tm->tm_mday = i; // printf("Day of the month: %d\n", tm->tm_mday); while(rfc2822_is_wsp(*t)) t++; h = t; /* Month */ t = rfc2822_next_token(t, ' ', "\t"); if (t == NULL) return 0; *t++ = '\0'; for (i = 0; months[i]; i++) { if (!(strcasecmp(months[i], h))) break; } if (months[i] == NULL) return 0; tm->tm_mon = i; // printf("Month: %d [%s]\n", i, months[i]); while(rfc2822_is_wsp(*t)) t++; h = t; /* Year */ t = rfc2822_next_token(t, ' ', "\t"); if (t == NULL) return 0; *t++ = '\0'; i = atoi(h); if ((i == 0) || (i < 1900)) return 0; tm->tm_year = (i - 1900); // printf("Year: %d\n", tm->tm_year+1900); while(rfc2822_is_wsp(*t)) t++; h = t; /* Hours */ t = rfc2822_next_token(t, ':', NULL); if (t == NULL) return 0; *t++ = '\0'; i = atoi(h); if ((i < 0) || (i > 23)) return 0; tm->tm_hour = i; // printf("Hour: %d\n", tm->tm_hour); while(rfc2822_is_wsp(*t)) t++; h = t; /* Minutes */ t = rfc2822_next_token(t, ':', " \t"); if (t == NULL) return 0; c = *t; *t++ = '\0'; i = atoi(h); if ((i < 0) || (i > 59)) return 0; tm->tm_min = i; // printf("Minute: %d\n", tm->tm_min); /* Seconds (optional) */ if (c == ':') { while(rfc2822_is_wsp(*t)) t++; h = t; t = rfc2822_next_token(t, ' ', "\t"); if (t == NULL) return 0; *t++ = '\0'; i = atoi(h); if ((i < 0) || (i > 60)) return 0; tm->tm_sec = i; // printf("Second: %d\n", tm->tm_sec); } while(rfc2822_is_wsp(*t)) t++; h = t; /* UTC offset or TZ string */ while((*t) && (!(rfc2822_is_wsp(*t)))) t++; if (rfc2822_is_wsp(*t)) *t = '\0'; c = *h++; /* Timezone specification we don't care about */ if ((c != '+') && (c != '-')) return 1; utc[0] = *h++; utc[1] = *h++; utc[2] = '\0'; i = atoi(utc); tm->tm_gmtoff = ((i * 60) * 60); utc[0] = *h++; utc[1] = *h++; i = atoi(utc); tm->tm_gmtoff += (i * 60); if (c == '-') tm->tm_gmtoff = -(tm->tm_gmtoff); // printf("Offset: %ld\n", tm->tm_gmtoff); return 1; }