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