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