This is pack_date.c in view mode; [Download] [Up]
/* * (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 !! */ #undef W #undef E #undef DST #undef UTC #define W * (-60) - #define E * 60 + #define DST + 60 #define UTC 60 * static struct zonetab { char *tz_name; int32 tz_offset; } ztab[] = { "a", UTC 1, /* UTC+1h */ "acsst", 9 E 30 DST, /* Cent. Australia */ "acst", 9 E 30, /* Cent. Australia */ "adt", 4 W 0 DST, /* Atlantic (Canada) */ "aesst", 10 E 0 DST, /* E. Australia */ "aest", 10 E 0, /* E. Australia */ "ast", 4 W 0, /* Atlantic (Canada) */ "awsst", 8 E 0 DST, /* W. Australia */ "awst", 8 E 0, /* W. Australia */ "b", UTC 2, /* UTC+2h */ "bst", 0 E 0 DST, /* Great Britain summertime */ "c", UTC 3, /* UTC+3h */ "cdt", 6 W 0 DST, /* Central */ "cest", 1 E 0 DST, /* Central Europe */ "cet", 1 E 0, /* Central Europe */ "cetdst", 1 E 0 DST, /* Central Europe */ "cst", 6 W 0, /* Central */ "d", UTC 4, /* UTC+4h */ "dnt", 1 E 0, /* Denmark */ "dst", 1 E 0 DST, /* Denmark */ "e", UTC 5, /* UTC+5h */ "edt", 5 W 0 DST, /* Eastern US */ "eest", 2 E 0 DST, /* Eastern Europe */ "eet", 2 E 0, /* Eastern Europe */ "eetdst", 2 E 0 DST, /* Eastern Europe */ "est", 5 W 0, /* Eastern US */ "f", UTC 6, /* UTC+6h */ "g", UTC 7, /* UTC+7h */ "gmt", 0, /* */ "h", UTC 8, /* UTC+8h */ "hdt", 10 W 0 DST, /* Hawaii/Alaska */ "hst", 10 W 0, /* Hawaii/Alaska */ "i", UTC 9, /* UTC+9h */ "ist", 2 E 0, /* Israel */ "jst", 9 E 0, /* Japan */ "k", UTC 10, /* UTC+10h */ "l", UTC 11, /* UTC+11h */ "m", UTC 12, /* UTC+12h */ "mdt", 7 W 0 DST, /* Mountain US */ "mest", 1 E 0 DST, /* Central Europe */ "met", 1 E 0, /* Central Europe */ "metdst", 1 E 0 DST, /* Central Europe */ "mst", 7 W 0, /* Mountain */ "n", UTC -1, /* UTC-1h */ "ndt", 3 W 30 DST, /* Nfld. (Canada) */ "nst", 3 W 30, /* Nfld. (Canada) */ "o", UTC -2, /* UTC-2h */ "p", UTC -3, /* UTC-3h */ "pdt", 8 W 0 DST, /* Pacific */ "pst", 8 W 0, /* Pacific */ "q", UTC -4, /* UTC-4h */ "r", UTC -5, /* UTC-5h */ "s", UTC -6, /* UTC-6h */ "t", UTC -7, /* UTC-7h */ "u", UTC -8, /* UTC-8h */ "ut", UTC 0, /* UTC */ "utc", UTC 0, /* UTC */ "v", UTC -9, /* UTC-9h */ "w", UTC -10, /* UTC-10h */ "west", 0 E 0 DST, /* Western Europe */ "wet", 0 E 0, /* Western Europe */ "wetdst", 0 E 0 DST, /* Western Europe */ "x", UTC -11, /* UTC-11h */ "y", UTC -12, /* UTC-12h */ "ydt", 9 W 0 DST, /* Yukon */ "yst", 9 W 0, /* Yukon */ "z", UTC 0, /* UTC */ NULL, 0 }; #undef MAXZ #define MAXZ 10 static long tzone(date) register char *date; { register int i, n; static char zone[MAXZ], num[MAXZ]; register struct zonetab *z; long adjust, sign; static int first = 1; i = 0; while (*date && isascii(*date) && isspace(*date)) date++; for ( ; *date && isascii(*date) ; date++) { if (*date == '+' || *date == '-' || isdigit(*date)) goto numeric_zone; if (isspace(*date)) break; if (!isalpha(*date)) continue; /* p.s.t. -> pst */ if (i == MAXZ) continue; zone[i++] = isupper(*date) ? tolower(*date) : *date; } while (*date && isascii(*date) && isspace(*date)) date++; if (*date && i < MAXZ-3) { if (date[0] != 'D' && date[0] != 'd') goto no_dst; if (date[1] != 'S' && date[1] != 's') goto no_dst; if (date[2] != 'T' && date[2] != 't') goto no_dst; zone[i++] = 'd'; zone[i++] = 's'; zone[i++] = 't'; } no_dst: if (i == 0) return 0; adjust = 0; if (*date != '+' && *date != '-') goto non_numeric; numeric_zone: /* {+-}[H]H[MM] */ switch (*date) { case '-': date++; sign = -1; break; case '+': date++; default: sign = 1; break; } adjust = 0; for (n = 0; n < MAXZ && *date && isascii(*date) && isdigit(*date); ) num[n++] = *date++; num[n] = NUL; switch (n) { case 0: break; case 3: /* +HMM */ adjust = atoi(num+1); case 1: /* +H */ adjust += (num[0] - '0') * 60; break; case 2: /* +HH */ adjust = atoi(num) * 60; break; default: /* +HHMM */ if (num[2] != '0' || num[3] != '0') { num[4] = NUL; adjust = atoi(num + 2); } num[2] = NUL; adjust += atoi(num) * 60; break; } adjust *= sign; if (i == 0) return adjust; non_numeric: zone[i] = NUL; for (z = ztab; z->tz_name != NULL; z++) { if ((i = strcmp(zone, z->tz_name)) > 0) continue; if (i < 0) break; return z->tz_offset + adjust; } return adjust; } 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++; if (date[0] == NUL || date[1] == NUL || date[2] == NUL) return 0; switch (date[0]) { case 'J': case 'j': if (date[1] == 'a' || date[1] == 'A') { mon = 0; break; } if (date[2] == 'n' || date[2] == 'N') { mon = 5; break; } mon = 6; break; case 'F': case 'f': mon = 1; break; case 'M': case 'm': if (date[2] == 'r' || date[2] == 'R') { mon = 2; break; } mon = 4; break; case 'A': case 'a': if (date[1] == 'p' || date[1] == 'P') { mon = 3; break; } mon = 7; break; case 'S': case 's': mon = 8; break; case 'O': case 'o': mon = 9; break; case 'N': case 'n': mon = 10; break; case 'D': case 'd': mon = 11; break; default: return 0; } year = next_int(&date); hour = next_int(&date); min = next_int(&date); if (*date == ':') next_int(&date); if (year >= 100) year -= 1900; /* xxYY -> YY */ 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
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.