home *** CD-ROM | disk | FTP | other *** search
- /*
- * (c) Copyright 1990, Kim Fabricius Storm. All rights reserved.
- *
- * Calculate an approximate "time_stamp" value for a date
- * string. The actual value is not at all critical,
- * as long as the "ordering" is ok.
- *
- * The result is NOT a time_t value, i.e. ctime() will
- * not produce the original Date string.
- *
- * The date must have format: [...,] [D]D Mmm YY hh:mm:ss TZONE
- *
- * Thanks to Wayne Davison for the timezone decoding code.
- */
-
- #include "config.h"
-
- /* #define DATE_TEST /* never define this !! */
-
- static long wtz(h, m, c)
- int h, m;
- char c;
- {
- if (c != 's') h--; /* daylight savings */
- return h*60L+m*30L;
- }
-
- static long etz(h, m, c)
- int h, m;
- char c;
- {
- if (c == 's') h++; /* summer time */
- return -(h*60L+m*30L);
- }
-
- #define TOLOWER(ch) (isupper(ch) ? tolower(ch) : (ch))
-
- static long tzone(date)
- register char *date;
- {
- char ch1, ch2, ch3, ch4;
- long tz, wtz(), etz();
-
- while (*date && !isalpha(*date)) date++;
- if (*date == NUL || *date == 'G') return 0;
-
- ch1 = TOLOWER(*date);
- while (date++, (ch2 = TOLOWER(*date)) == '.') /* p.s.t. -> pst */
- ;
- while (date++, (ch3 = TOLOWER(*date)) == '.')
- ;
- while (date++, (ch4 = TOLOWER(*date)) == '.')
- ;
- switch (ch1) {
- case 'n':
- tz = wtz(3,1,0); break; /* Newfoundland: nst */
- case 'a':
- if (ch2 == 'e') {
- tz = etz(10,0,ch4); break; /* Australian Eastern: aest, aesst */
- }
- if (ch2 == 'c') {
- tz = etz(9,1,ch4); break; /* Australian Central: acst, acsst */
- }
- if (ch2 == 'w') {
- tz = etz(8,1,ch4); break; /* Australian Western: awst, awsst */
- }
- tz = wtz(4,0,ch2); break; /* Atlantic: ast, adt */
- case 'b':
- tz = etz(1,0,0); break; /* British summer: bst */
- case 'c':
- tz = wtz(6,0,ch2); break; /* Central: cst, cdt */
- case 'e':
- if (ch2 == 'e') {
- tz = etz(0,0,ch3); break; /* European Eastern: eet, eest */
- }
- tz = wtz(5,0,ch2); break; /* Eastern: est, edt */
- case 'g':
- tz = etz(0,0,0); break; /* Greenwich: gmt */
- case 'h':
- tz = wtz(10,0,ch2); break; /* Hawaii: hst, hdt */
- case 'j':
- tz = etz(9,0,0); break; /* Japan: jst */
- case 'm':
- if (ch2 == 'e') {
- tz = etz(1,0,ch3); break; /* Middle European: met, mest */
- }
- tz = wtz(7,0,ch2); break; /* Mountain: mst, mdt */
- case 'p':
- tz = wtz(8,0,ch2); break; /* Pacific: pst, pdt */
- case 'w':
- tz = etz(2,0,ch3); break; /* Western European: wet, west */
- case 'y':
- tz = wtz(9,0,ch2); break; /* Yukon: yst, ydt */
- default:
- tz = 0; break; /* use GMT if we can't understand it */
- }
-
- return tz;
- }
-
- static next_int(dp)
- char **dp;
- {
- register char *str = *dp;
- register i;
-
- while (*str && !isdigit(*str)) str++;
-
- i = 0;
- while (*str && isdigit(*str))
- i = (i * 10) + *str++ - '0';
-
- *dp = str;
- return i;
- }
-
- time_stamp pack_date(date)
- char *date;
- {
- register time_stamp res;
- register int min, hour, day, mon, year;
-
- if (date == NULL || (day = next_int(&date)) == 0) return 0;
-
- while (*date && isspace(*date)) date++;
-
- switch (*date++) {
- case 'J':
- if (*date++ == 'a') { mon = 0; break; }
- if (*date++ == 'n') { mon = 5; break; }
- mon = 6; break;
- case 'F':
- mon = 1; break;
- case 'M':
- if (*++date == 'r') { mon = 2; break; }
- mon = 4; break;
- case 'A':
- if (*date++ == 'p') { mon = 3; break; }
- mon = 7; break;
- case 'S':
- mon = 8; break;
- case 'O':
- mon = 9; break;
- case 'N':
- mon = 10; break;
- case 'D':
- mon = 11; break;
- default:
- return 0;
- }
-
- year = next_int(&date);
- hour = next_int(&date);
- min = next_int(&date);
-
- year -= 87; /* base is 1987 */
- if (year < 0) year += 100;
-
- res = (year * 12 + mon) * 31 + day - 1;
- res *= 24 * 60;
- res += (hour * 60) + min;
-
- return res + tzone(date);
- }
-
-
- #ifdef DATE_TEST
-
-
- main()
- {
- char buffer[128];
- char *dp;
- unsigned long t;
-
- while (fgets(buffer, 128, stdin)) {
- if (strncmp(buffer, "Date:", 5)) continue;
-
- dp = strchr(buffer, ':');
- if (dp == NULL) continue;
- dp++;
- while (isspace(*dp)) dp++;
- t = pack_date(dp);
- printf("%lu\t%s\n", t, dp);
- }
-
- exit(0);
- }
-
- #endif
-