1: %token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO
   2: %{
   3:     /* 	Steven M. Bellovin (unc!smb)			*/
   4:     /*	Dept. of Computer Science			*/
   5:     /*	University of North Carolina at Chapel Hill	*/
   6:     /*	@(#)getdate.y	2.12	4/16/85	*/
   7: 
   8: #include <sys/types.h>
   9: #ifdef USG
  10: struct timeb
  11: {
  12:     time_t  time;
  13:     unsigned short millitm;
  14:     short   timezone;
  15:     short   dstflag;
  16: };
  17: #else
  18: #include <sys/timeb.h>
  19: #endif
  20: #include <ctype.h>
  21: 
  22: #include "defs.h"
  23: #if defined(BSD4_2) || defined (BSD4_1C)
  24: #include <sys/time.h>
  25: #else sane
  26: #include <time.h>
  27: #endif sane
  28: 
  29: #define NULL    0
  30: #define daysec (24L*60L*60L)
  31:     static int timeflag, zoneflag, dateflag, dayflag, relflag;
  32:     static time_t relsec, relmonth;
  33:     static int hh, mm, ss, merid, daylight;
  34:     static int dayord, dayreq;
  35:     static int month, day, year;
  36:     static int ourzone;
  37: #define AM 1
  38: #define PM 2
  39: #define DAYLIGHT 1
  40: #define STANDARD 2
  41: #define MAYBE    3
  42: %}
  43: 
  44: %%
  45: timedate:       /* empty */
  46:     | timedate item;
  47: 
  48: item:   tspec =
  49:         {timeflag++;}
  50:     | zone =
  51:         {zoneflag++;}
  52:     | dtspec =
  53:         {dateflag++;}
  54:     | dyspec =
  55:         {dayflag++;}
  56:     | rspec =
  57:         {relflag++;}
  58:     | nspec;
  59: 
  60: nspec:  NUMBER =
  61:         {if (timeflag && dateflag && !relflag) year = $1;
  62:         else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}};
  63: 
  64: tspec:  NUMBER MERIDIAN =
  65:         {hh = $1; mm = 0; ss = 0; merid = $2;}
  66:     | NUMBER ':' NUMBER =
  67:         {hh = $1; mm = $3; merid = 24;}
  68:     | NUMBER ':' NUMBER MERIDIAN =
  69:         {hh = $1; mm = $3; merid = $4;}
  70:     | NUMBER ':' NUMBER ':' NUMBER =
  71:         {hh = $1; mm = $3; ss = $5; merid = 24;}
  72:     | NUMBER ':' NUMBER ':' NUMBER MERIDIAN =
  73:         {hh = $1; mm = $3; ss = $5; merid = $6;};
  74: 
  75: zone:   ZONE =
  76:         {ourzone = $1; daylight = STANDARD;}
  77:     | DAYZONE =
  78:         {ourzone = $1; daylight = DAYLIGHT;};
  79: 
  80: dyspec: DAY =
  81:         {dayord = 1; dayreq = $1;}
  82:     | DAY ',' =
  83:         {dayord = 1; dayreq = $1;}
  84:     | NUMBER DAY =
  85:         {dayord = $1; dayreq = $2;};
  86: 
  87: dtspec: NUMBER '/' NUMBER =
  88:         {month = $1; day = $3;}
  89:     | NUMBER '/' NUMBER '/' NUMBER =
  90:         {month = $1; day = $3; year = $5;}
  91:     | MONTH NUMBER =
  92:         {month = $1; day = $2;}
  93:     | MONTH NUMBER ',' NUMBER =
  94:         {month = $1; day = $2; year = $4;}
  95:     | NUMBER MONTH =
  96:         {month = $2; day = $1;}
  97:     | NUMBER MONTH NUMBER =
  98:         {month = $2; day = $1; year = $3;};
  99: 
 100: 
 101: rspec:  NUMBER UNIT =
 102:         {relsec +=  60L * $1 * $2;}
 103:     | NUMBER MUNIT =
 104:         {relmonth += $1 * $2;}
 105:     | NUMBER SUNIT =
 106:         {relsec += $1;}
 107:     | UNIT =
 108:         {relsec +=  60L * $1;}
 109:     | MUNIT =
 110:         {relmonth += $1;}
 111:     | SUNIT =
 112:         {relsec++;}
 113:     | rspec AGO =
 114:         {relsec = -relsec; relmonth = -relmonth;};
 115: %%
 116: 
 117: static int mdays[12] =
 118:     {31, 0, 31,  30, 31, 30,  31, 31, 30,  31, 30, 31};
 119: #define epoch 1970
 120: 
 121: extern struct tm *localtime();
 122: time_t dateconv(mm, dd, yy, h, m, s, mer, zone, dayflag)
 123: int mm, dd, yy, h, m, s, mer, zone, dayflag;
 124: {
 125:     time_t tod, jdate;
 126:     register int i;
 127:     time_t timeconv();
 128: 
 129:     if (yy < 0) yy = -yy;
 130:     if (yy < 100) yy += 1900;
 131:     mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0));
 132:     if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 ||
 133:         dd < 1 || dd > mdays[--mm]) return (-1);
 134:     jdate = dd-1;
 135:         for (i=0; i<mm; i++) jdate += mdays[i];
 136:     for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0);
 137:     jdate *= daysec;
 138:     jdate += zone * 60L;
 139:     if ((tod = timeconv(h, m, s, mer)) < 0) return (-1);
 140:     jdate += tod;
 141:     if (dayflag==DAYLIGHT || (dayflag==MAYBE&&localtime(&jdate)->tm_isdst))
 142:         jdate += -1*60*60;
 143:     return (jdate);
 144: }
 145: 
 146: time_t dayconv(ord, day, now) int ord, day; time_t now;
 147: {
 148:     register struct tm *loctime;
 149:     time_t tod;
 150:     time_t daylcorr();
 151: 
 152:     tod = now;
 153:     loctime = localtime(&tod);
 154:     tod += daysec * ((day - loctime->tm_wday + 7) % 7);
 155:     tod += 7*daysec*(ord<=0?ord:ord-1);
 156:     return daylcorr(tod, now);
 157: }
 158: 
 159: time_t timeconv(hh, mm, ss, mer) register int hh, mm, ss, mer;
 160: {
 161:     if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1);
 162:     switch (mer) {
 163:         case AM: if (hh < 1 || hh > 12) return(-1);
 164:              return (60L * ((hh%12)*60L + mm)+ss);
 165:         case PM: if (hh < 1 || hh > 12) return(-1);
 166:              return (60L * ((hh%12 +12)*60L + mm)+ss);
 167:         case 24: if (hh < 0 || hh > 23) return (-1);
 168:              return (60L * (hh*60L + mm)+ss);
 169:         default: return (-1);
 170:     }
 171: }
 172: time_t monthadd(sdate, relmonth) time_t sdate, relmonth;
 173: {
 174:     struct tm *ltime;
 175:     time_t dateconv();
 176:     time_t daylcorr();
 177:     int mm, yy;
 178: 
 179:     if (relmonth == 0) return 0;
 180:     ltime = localtime(&sdate);
 181:     mm = 12*ltime->tm_year + ltime->tm_mon + relmonth;
 182:     yy = mm/12;
 183:     mm = mm%12 + 1;
 184:     return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour,
 185:         ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate);
 186: }
 187: 
 188: time_t daylcorr(future, now) time_t future, now;
 189: {
 190:     int fdayl, nowdayl;
 191: 
 192:     nowdayl = (localtime(&now)->tm_hour+1) % 24;
 193:     fdayl = (localtime(&future)->tm_hour+1) % 24;
 194:     return (future-now) + 60L*60L*(nowdayl-fdayl);
 195: }
 196: 
 197: static char *lptr;
 198: 
 199: yylex()
 200: {
 201:     extern int yylval;
 202:     int sign;
 203:     register char c;
 204:     register char *p;
 205:     char idbuf[20];
 206:     int pcnt;
 207: 
 208:     for (;;) {
 209:         while (isspace(*lptr)) lptr++;
 210: 
 211:         if (isdigit(c = *lptr) || c == '-' || c == '+') {
 212:             if (c== '-' || c == '+') {
 213:                 if (c=='-') sign = -1;
 214:                 else sign = 1;
 215:                 if (!isdigit(*++lptr)) {
 216:                     /* yylval = sign; return (NUMBER); */
 217:                     return yylex(); /* skip the '-' sign */
 218:                 }
 219:             } else sign = 1;
 220:             yylval = 0;
 221:             while (isdigit(c = *lptr++)) yylval = 10*yylval + c - '0';
 222:             yylval *= sign;
 223:             lptr--;
 224:             return (NUMBER);
 225: 
 226:         } else if (isalpha(c)) {
 227:             p = idbuf;
 228:             while (isalpha(c = *lptr++) || c=='.')
 229:                 *p++ = c;
 230:             *p = '\0';
 231:             lptr--;
 232:             return (lookup(idbuf));
 233:         }
 234: 
 235:         else if (c == '(') {
 236:             pcnt = 0;
 237:             do {
 238:                 c = *lptr++;
 239:                 if (c == '\0') return(c);
 240:                 else if (c == '(') pcnt++;
 241:                 else if (c == ')') pcnt--;
 242:             } while (pcnt > 0);
 243:         }
 244: 
 245:         else return (*lptr++);
 246:     }
 247: }
 248: 
 249: struct table {
 250:     char *name;
 251:     int type, value;
 252: };
 253: 
 254: struct table mdtab[] = {
 255:     {"January", MONTH, 1},
 256:     {"February", MONTH, 2},
 257:     {"March", MONTH, 3},
 258:     {"April", MONTH, 4},
 259:     {"May", MONTH, 5},
 260:     {"June", MONTH, 6},
 261:     {"July", MONTH, 7},
 262:     {"August", MONTH, 8},
 263:     {"September", MONTH, 9},
 264:     {"Sept", MONTH, 9},
 265:     {"October", MONTH, 10},
 266:     {"November", MONTH, 11},
 267:     {"December", MONTH, 12},
 268: 
 269:     {"Sunday", DAY, 0},
 270:     {"Monday", DAY, 1},
 271:     {"Tuesday", DAY, 2},
 272:     {"Tues", DAY, 2},
 273:     {"Wednesday", DAY, 3},
 274:     {"Wednes", DAY, 3},
 275:     {"Thursday", DAY, 4},
 276:     {"Thur", DAY, 4},
 277:     {"Thurs", DAY, 4},
 278:     {"Friday", DAY, 5},
 279:     {"Saturday", DAY, 6},
 280:     {0, 0, 0}};
 281: 
 282: #define HRS *60
 283: #define HALFHR 30
 284: struct table mztab[] = {
 285:     {"a.m.", MERIDIAN, AM},
 286:     {"am", MERIDIAN, AM},
 287:     {"p.m.", MERIDIAN, PM},
 288:     {"pm", MERIDIAN, PM},
 289:     {"nst", ZONE, 3 HRS + HALFHR},      /* Newfoundland */
 290:     {"n.s.t.", ZONE, 3 HRS + HALFHR},
 291:     {"ast", ZONE, 4 HRS},       /* Atlantic */
 292:     {"a.s.t.", ZONE, 4 HRS},
 293:     {"adt", DAYZONE, 4 HRS},
 294:     {"a.d.t.", DAYZONE, 4 HRS},
 295:     {"est", ZONE, 5 HRS},       /* Eastern */
 296:     {"e.s.t.", ZONE, 5 HRS},
 297:     {"edt", DAYZONE, 5 HRS},
 298:     {"e.d.t.", DAYZONE, 5 HRS},
 299:     {"cst", ZONE, 6 HRS},       /* Central */
 300:     {"c.s.t.", ZONE, 6 HRS},
 301:     {"cdt", DAYZONE, 6 HRS},
 302:     {"c.d.t.", DAYZONE, 6 HRS},
 303:     {"mst", ZONE, 7 HRS},       /* Mountain */
 304:     {"m.s.t.", ZONE, 7 HRS},
 305:     {"mdt", DAYZONE, 7 HRS},
 306:     {"m.d.t.", DAYZONE, 7 HRS},
 307:     {"pst", ZONE, 8 HRS},       /* Pacific */
 308:     {"p.s.t.", ZONE, 8 HRS},
 309:     {"pdt", DAYZONE, 8 HRS},
 310:     {"p.d.t.", DAYZONE, 8 HRS},
 311:     {"yst", ZONE, 9 HRS},       /* Yukon */
 312:     {"y.s.t.", ZONE, 9 HRS},
 313:     {"ydt", DAYZONE, 9 HRS},
 314:     {"y.d.t.", DAYZONE, 9 HRS},
 315:     {"hst", ZONE, 10 HRS},      /* Hawaii */
 316:     {"h.s.t.", ZONE, 10 HRS},
 317:     {"hdt", DAYZONE, 10 HRS},
 318:     {"h.d.t.", DAYZONE, 10 HRS},
 319: 
 320:     {"gmt", ZONE, 0 HRS},
 321:     {"g.m.t.", ZONE, 0 HRS},
 322:     {"bst", DAYZONE, 0 HRS},        /* British Summer Time */
 323:     {"b.s.t.", DAYZONE, 0 HRS},
 324:     {"eet", ZONE, 0 HRS},       /* European Eastern Time */
 325:     {"e.e.t.", ZONE, 0 HRS},
 326:     {"eest", DAYZONE, 0 HRS},   /* European Eastern Summer Time */
 327:     {"e.e.s.t.", DAYZONE, 0 HRS},
 328:     {"met", ZONE, -1 HRS},      /* Middle European Time */
 329:     {"m.e.t.", ZONE, -1 HRS},
 330:     {"mest", DAYZONE, -1 HRS},  /* Middle European Summer Time */
 331:     {"m.e.s.t.", DAYZONE, -1 HRS},
 332:     {"wet", ZONE, -2 HRS },     /* Western European Time */
 333:     {"w.e.t.", ZONE, -2 HRS },
 334:     {"west", DAYZONE, -2 HRS},  /* Western European Summer Time */
 335:     {"w.e.s.t.", DAYZONE, -2 HRS},
 336: 
 337:     {"jst", ZONE, -9 HRS},      /* Japan Standard Time */
 338:     {"j.s.t.", ZONE, -9 HRS},   /* Japan Standard Time */
 339:                     /* No daylight savings time */
 340: 
 341:     {"aest", ZONE, -10 HRS},    /* Australian Eastern Time */
 342:     {"a.e.s.t.", ZONE, -10 HRS},
 343:     {"aesst", DAYZONE, -10 HRS},    /* Australian Eastern Summer Time */
 344:     {"a.e.s.s.t.", DAYZONE, -10 HRS},
 345:     {"acst", ZONE, -(9 HRS + HALFHR)},  /* Australian Central Time */
 346:     {"a.c.s.t.", ZONE, -(9 HRS + HALFHR)},
 347:     {"acsst", DAYZONE, -(9 HRS + HALFHR)},  /* Australian Central Summer */
 348:     {"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)},
 349:     {"awst", ZONE, -8 HRS},     /* Australian Western Time */
 350:     {"a.w.s.t.", ZONE, -8 HRS}, /* (no daylight time there, I'm told */
 351:     {0, 0, 0}};
 352: 
 353: struct table unittb[] = {
 354:     {"year", MUNIT, 12},
 355:     {"month", MUNIT, 1},
 356:     {"fortnight", UNIT, 14*24*60},
 357:     {"week", UNIT, 7*24*60},
 358:     {"day", UNIT, 1*24*60},
 359:     {"hour", UNIT, 60},
 360:     {"minute", UNIT, 1},
 361:     {"min", UNIT, 1},
 362:     {"second", SUNIT, 1},
 363:     {"sec", SUNIT, 1},
 364:     {0, 0, 0}};
 365: 
 366: struct table othertb[] = {
 367:     {"tomorrow", UNIT, 1*24*60},
 368:     {"yesterday", UNIT, -1*24*60},
 369:     {"today", UNIT, 0},
 370:     {"now", UNIT, 0},
 371:     {"last", NUMBER, -1},
 372:     {"this", UNIT, 0},
 373:     {"next", NUMBER, 2},
 374:     {"first", NUMBER, 1},
 375:     /* {"second", NUMBER, 2}, */
 376:     {"third", NUMBER, 3},
 377:     {"fourth", NUMBER, 4},
 378:     {"fifth", NUMBER, 5},
 379:     {"sixth", NUMBER, 6},
 380:     {"seventh", NUMBER, 7},
 381:     {"eigth", NUMBER, 8},
 382:     {"ninth", NUMBER, 9},
 383:     {"tenth", NUMBER, 10},
 384:     {"eleventh", NUMBER, 11},
 385:     {"twelfth", NUMBER, 12},
 386:     {"ago", AGO, 1},
 387:     {0, 0, 0}};
 388: 
 389: struct table milzone[] = {
 390:     {"a", ZONE, 1 HRS},
 391:     {"b", ZONE, 2 HRS},
 392:     {"c", ZONE, 3 HRS},
 393:     {"d", ZONE, 4 HRS},
 394:     {"e", ZONE, 5 HRS},
 395:     {"f", ZONE, 6 HRS},
 396:     {"g", ZONE, 7 HRS},
 397:     {"h", ZONE, 8 HRS},
 398:     {"i", ZONE, 9 HRS},
 399:     {"k", ZONE, 10 HRS},
 400:     {"l", ZONE, 11 HRS},
 401:     {"m", ZONE, 12 HRS},
 402:     {"n", ZONE, -1 HRS},
 403:     {"o", ZONE, -2 HRS},
 404:     {"p", ZONE, -3 HRS},
 405:     {"q", ZONE, -4 HRS},
 406:     {"r", ZONE, -5 HRS},
 407:     {"s", ZONE, -6 HRS},
 408:     {"t", ZONE, -7 HRS},
 409:     {"u", ZONE, -8 HRS},
 410:     {"v", ZONE, -9 HRS},
 411:     {"w", ZONE, -10 HRS},
 412:     {"x", ZONE, -11 HRS},
 413:     {"y", ZONE, -12 HRS},
 414:     {"z", ZONE, 0 HRS},
 415:     {0, 0, 0}};
 416: 
 417: lookup(id) char *id;
 418: {
 419: #define gotit (yylval=i->value,  i->type)
 420: #define getid for(j=idvar, k=id; *j++ = *k++; )
 421: 
 422:     char idvar[20];
 423:     register char *j, *k;
 424:     register struct table *i;
 425:     int abbrev;
 426: 
 427:     getid;
 428:     if (strlen(idvar) == 3) abbrev = 1;
 429:     else if (strlen(idvar) == 4 && idvar[3] == '.') {
 430:         abbrev = 1;
 431:         idvar[3] = '\0';
 432:     }
 433:     else abbrev = 0;
 434: 
 435:     if (islower(*idvar)) *idvar = toupper(*idvar);
 436: 
 437:     for (i = mdtab; i->name; i++) {
 438:         k = idvar;
 439:         for (j = i->name; *j++ == *k++;) {
 440:             if (abbrev && j==i->name+3) return gotit;
 441:             if (j[-1] == 0) return gotit;
 442:         }
 443:     }
 444: 
 445:     getid;
 446:     for (i = mztab; i->name; i++)
 447:         if (strcmp(i->name, idvar) == 0) return gotit;
 448: 
 449:     for (j = idvar; *j; j++) if (isupper(*j)) *j = tolower(*j);
 450:     for (i=mztab; i->name; i++)
 451:         if (strcmp(i->name, idvar) == 0) return gotit;
 452: 
 453:     getid;
 454:     for (i=unittb; i->name; i++)
 455:         if (strcmp(i->name, idvar) == 0) return gotit;
 456: 
 457:     if (idvar[strlen(idvar)-1] == 's') idvar[strlen(idvar)-1] = '\0';
 458:     for (i=unittb; i->name; i++)
 459:         if (strcmp(i->name, idvar) == 0) return gotit;
 460: 
 461:     getid;
 462:     for (i = othertb; i->name; i++)
 463:         if (strcmp(i->name, idvar) == 0) return gotit;
 464: 
 465:     getid;
 466:     if (strlen(idvar) == 1 && isalpha(*idvar)) {
 467:         if (isupper(*idvar)) *idvar = tolower(*idvar);
 468:         for (i = milzone; i->name; i++)
 469:             if (strcmp(i->name, idvar) == 0) return gotit;
 470:     }
 471: 
 472:     return(ID);
 473: }
 474: 
 475: time_t getdate(p, now) char *p; struct timeb *now;
 476: {
 477: #define mcheck(f)   if (f>1) err++
 478:     time_t monthadd();
 479:     int err;
 480:     struct tm *lt;
 481:     struct timeb ftz;
 482: 
 483:     time_t sdate, tod;
 484: 
 485:     lptr = p;
 486:     if (now == ((struct timeb *) NULL)) {
 487:         now = &ftz;
 488:         ftime(&ftz);
 489:     }
 490:     lt = localtime(&now->time);
 491:     year = lt->tm_year;
 492:     month = lt->tm_mon+1;
 493:     day = lt->tm_mday;
 494:     relsec = 0; relmonth = 0;
 495:     timeflag=zoneflag=dateflag=dayflag=relflag=0;
 496:     ourzone = now->timezone;
 497:     daylight = MAYBE;
 498:     hh = mm = ss = 0;
 499:     merid = 24;
 500: 
 501:     if (err = yyparse()) return (-1);
 502: 
 503:     mcheck(timeflag);
 504:     mcheck(zoneflag);
 505:     mcheck(dateflag);
 506:     mcheck(dayflag);
 507: 
 508:     if (err) return (-1);
 509:     if (dateflag || timeflag || dayflag) {
 510:         sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylight);
 511:         if (sdate < 0) return -1;
 512:     }
 513:     else {
 514:         sdate = now->time;
 515:         if (relflag == 0)
 516:             sdate -= (lt->tm_sec + lt->tm_min*60 +
 517:                 lt->tm_hour*(60L*60L));
 518:     }
 519: 
 520:     sdate += relsec;
 521:     sdate += monthadd(sdate, relmonth);
 522: 
 523:     if (dayflag && !dateflag) {
 524:         tod = dayconv(dayord, dayreq, sdate);
 525:         sdate += tod;
 526:     }
 527: 
 528:     return sdate;
 529: }
 530: 
 531: yyerror(s) char *s;
 532: {}

Defined functions

_dateconv defined in line 122; used 3 times
_dayconv defined in line 146; used 1 times
_daylcorr defined in line 188; used 4 times
_getdate defined in line 475; used 3 times
_lookup defined in line 417; used 1 times
_monthadd defined in line 172; used 2 times
_timeconv defined in line 159; used 2 times
_yyerror defined in line 531; never used
_yylex defined in line 199; used 1 times

Defined variables

_lptr defined in line 197; used 11 times
_mdays defined in line 117; used 3 times
_mdtab defined in line 254; used 1 times
_milzone defined in line 389; used 1 times
_mztab defined in line 284; used 2 times
_othertb defined in line 366; used 1 times
_unittb defined in line 353; used 2 times

Defined struct's

table defined in line 249; used 12 times
timeb defined in line 10; used 6 times

Defined macros

AM defined in line 37; used 2 times
DAYLIGHT defined in line 39; used 2 times
HALFHR defined in line 283; used 6 times
HRS defined in line 282; used 83 times
MAYBE defined in line 41; used 3 times
NULL defined in line 29; used 1 times
PM defined in line 38; used 2 times
STANDARD defined in line 40; used 1 times
  • in line 76
daysec defined in line 30; used 3 times
epoch defined in line 119; used 2 times
getid defined in line 420; used 5 times
gotit defined in line 419; used 8 times
mcheck defined in line 477; used 4 times
Last modified: 1986-01-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1495
Valid CSS Valid XHTML 1.0 Strict