3 ** Originally written by Steven M. Bellovin <smb@research.att.com> while
4 ** at the University of North Carolina at Chapel Hill. Later tweaked by
5 ** a couple of people on Usenet. Completely overhauled by Rich $alz
6 ** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
7 ** send any email to Rich.
9 ** This grammar has nine shift/reduce conflicts.
11 ** This code is in the public domain and has no copyright.
13 /* SUPPRESS 287 on yaccpar_sccsid *//* Unusd static variable */
14 /* SUPPRESS 288 on yyerrlab *//* Label unused */
17 #if defined (emacs) || defined (CONFIG_BROKETS)
24 /* Since the code of getdate.y is not included in the Emacs executable
25 itself, there is no need to #define static in this file. Even if
26 the code were included in the Emacs executable, it probably
27 wouldn't do any harm to #undef it here; this will only cause
28 problems if we try to write to a static variable, which I don't
29 think this code needs to do. */
34 /* The following block of alloca-related preprocessor directives is here
35 solely to allow compilation by non GNU-C compilers of the C parser
36 produced from this file by old versions of bison. Newer versions of
37 bison include a block similar to this one in bison.simple. */
40 #define alloca __builtin_alloca
55 #define alloca __builtin_alloca
60 #ifdef _AIX /* for Bison */
71 /* The code at the top of get_date which figures out the offset of the
72 current time zone checks various CPP symbols to see if special
73 tricks are need, but defaults to using the gettimeofday system call.
74 Include <sys/time.h> if that will be used. */
83 #include <sys/types.h>
85 #ifdef TIME_WITH_SYS_TIME
89 #ifdef HAVE_SYS_TIME_H
97 #undef timezone /* needed for sgi */
100 #if defined(HAVE_SYS_TIMEB_H) || (!defined(USG) && defined(HAVE_FTIME))
101 #include <sys/timeb.h>
104 ** We use the obsolete `struct timeb' as part of our interface!
105 ** Since the system doesn't have it, we define it here;
106 ** our callers must do likewise.
109 time_t time
; /* Seconds since the epoch */
110 unsigned short millitm
; /* Field not used */
111 short timezone
; /* Minutes west of GMT */
112 short dstflag
; /* Field not used */
114 #endif /* defined(HAVE_SYS_TIMEB_H) */
116 #endif /* defined(vms) */
118 #if defined (STDC_HEADERS) || defined (USG)
122 /* Some old versions of bison generate parsers that use bcopy.
123 That loses on systems that don't provide the function, so we have
124 to redefine it here. */
125 #if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy)
126 #define bcopy(from, to, len) memcpy ((to), (from), (len))
129 extern
struct tm
*gmtime
();
130 extern
struct tm
*localtime
();
132 #define yyparse getdate_yyparse
133 #define yylex getdate_yylex
134 #define yyerror getdate_yyerror
137 static int yyerror ();
139 #if !defined(lint) && !defined(SABER)
141 "$Header: str2date.y,v 2.1 90/09/06 08:15:06 cronan Exp $";
142 #endif /* !defined(lint) && !defined(SABER) */
146 #define HOUR(x) ((time_t)(x) * 60)
147 #define SECSPERDAY (24L * 60L * 60L)
151 ** An entry in the lexical lookup table.
153 typedef
struct _TABLE
{
161 ** Daylight-savings mode: on, off, or not yet known.
163 typedef
enum _DSTMODE
{
164 DSTon
, DSToff
, DSTmaybe
168 ** Meridian: am, pm, or 24-hour style.
170 typedef
enum _MERIDIAN
{
176 ** Global variables. We could get rid of most of these by using a good
177 ** union as the yacc stack. (This routine was originally written before
178 ** yacc had the %union construct.) Maybe someday; right now we only use
179 ** the %union very rarely.
181 static char *yyInput
;
182 static DSTMODE yyDSTmode
;
183 static time_t yyDayOrdinal
;
184 static time_t yyDayNumber
;
185 static int yyHaveDate
;
186 static int yyHaveDay
;
187 static int yyHaveRel
;
188 static int yyHaveTime
;
189 static int yyHaveZone
;
190 static time_t yyTimezone
;
192 static time_t yyHour
;
193 static time_t yyMinutes
;
194 static time_t yyMonth
;
195 static time_t yySeconds
;
196 static time_t yyYear
;
197 static MERIDIAN yyMeridian
;
198 static time_t yyRelMonth
;
199 static time_t yyRelSeconds
;
205 enum _MERIDIAN Meridian
;
208 %token tAGO tDAY tDAYZONE tID tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT
209 %token tSEC_UNIT tSNUMBER tUNUMBER tZONE tDST
211 %type
<Number
> tDAY tDAYZONE tMINUTE_UNIT tMONTH tMONTH_UNIT
212 %type
<Number
> tSEC_UNIT tSNUMBER tUNUMBER tZONE
213 %type
<Meridian
> tMERIDIAN o_merid
239 time
: tUNUMBER tMERIDIAN
{
245 | tUNUMBER
':' tUNUMBER o_merid
{
251 | tUNUMBER
':' tUNUMBER tSNUMBER
{
256 yyTimezone
= - ($4 %
100 + ($4 / 100) * 60);
258 | tUNUMBER
':' tUNUMBER
':' tUNUMBER o_merid
{
264 | tUNUMBER
':' tUNUMBER
':' tUNUMBER tSNUMBER
{
270 yyTimezone
= - ($6 %
100 + ($6 / 100) * 60);
303 date
: tUNUMBER
'/' tUNUMBER
{
307 | tUNUMBER
'/' tUNUMBER
'/' tUNUMBER
{
312 | tUNUMBER tSNUMBER tSNUMBER
{
313 /* ISO 8601 format. yyyy-mm-dd. */
322 | tMONTH tUNUMBER
',' tUNUMBER
{
331 | tUNUMBER tMONTH tUNUMBER
{
339 yyRelSeconds
= -yyRelSeconds
;
340 yyRelMonth
= -yyRelMonth
;
345 relunit
: tUNUMBER tMINUTE_UNIT
{
346 yyRelSeconds
+= $1 * $2 * 60L;
348 | tSNUMBER tMINUTE_UNIT
{
349 yyRelSeconds
+= $1 * $2 * 60L;
352 yyRelSeconds
+= $1 * 60L;
354 | tSNUMBER tSEC_UNIT
{
357 | tUNUMBER tSEC_UNIT
{
363 | tSNUMBER tMONTH_UNIT
{
364 yyRelMonth
+= $1 * $2;
366 | tUNUMBER tMONTH_UNIT
{
367 yyRelMonth
+= $1 * $2;
375 if
(yyHaveTime
&& yyHaveDate
&& !yyHaveRel
)
383 yyDay
= (date_part
)%
100;
384 yyMonth
= (date_part
/100)%
100;
385 yyYear
= date_part
/10000;
394 yyMinutes
= $1 %
100;
402 o_merid
: /* NULL */ {
412 /* Month and day table. */
413 static TABLE
const MonthDayTable
[] = {
414 { "january", tMONTH
, 1 },
415 { "february", tMONTH
, 2 },
416 { "march", tMONTH
, 3 },
417 { "april", tMONTH
, 4 },
418 { "may", tMONTH
, 5 },
419 { "june", tMONTH
, 6 },
420 { "july", tMONTH
, 7 },
421 { "august", tMONTH
, 8 },
422 { "september", tMONTH
, 9 },
423 { "sept", tMONTH
, 9 },
424 { "october", tMONTH
, 10 },
425 { "november", tMONTH
, 11 },
426 { "december", tMONTH
, 12 },
427 { "sunday", tDAY
, 0 },
428 { "monday", tDAY
, 1 },
429 { "tuesday", tDAY
, 2 },
431 { "wednesday", tDAY
, 3 },
432 { "wednes", tDAY
, 3 },
433 { "thursday", tDAY
, 4 },
435 { "thurs", tDAY
, 4 },
436 { "friday", tDAY
, 5 },
437 { "saturday", tDAY
, 6 },
441 /* Time units table. */
442 static TABLE
const UnitsTable
[] = {
443 { "year", tMONTH_UNIT
, 12 },
444 { "month", tMONTH_UNIT
, 1 },
445 { "fortnight", tMINUTE_UNIT
, 14 * 24 * 60 },
446 { "week", tMINUTE_UNIT
, 7 * 24 * 60 },
447 { "day", tMINUTE_UNIT
, 1 * 24 * 60 },
448 { "hour", tMINUTE_UNIT
, 60 },
449 { "minute", tMINUTE_UNIT
, 1 },
450 { "min", tMINUTE_UNIT
, 1 },
451 { "second", tSEC_UNIT
, 1 },
452 { "sec", tSEC_UNIT
, 1 },
456 /* Assorted relative-time words. */
457 static TABLE
const OtherTable
[] = {
458 { "tomorrow", tMINUTE_UNIT
, 1 * 24 * 60 },
459 { "yesterday", tMINUTE_UNIT
, -1 * 24 * 60 },
460 { "today", tMINUTE_UNIT
, 0 },
461 { "now", tMINUTE_UNIT
, 0 },
462 { "last", tUNUMBER
, -1 },
463 { "this", tMINUTE_UNIT
, 0 },
464 { "next", tUNUMBER
, 2 },
465 { "first", tUNUMBER
, 1 },
466 /* { "second", tUNUMBER, 2 }, */
467 { "third", tUNUMBER
, 3 },
468 { "fourth", tUNUMBER
, 4 },
469 { "fifth", tUNUMBER
, 5 },
470 { "sixth", tUNUMBER
, 6 },
471 { "seventh", tUNUMBER
, 7 },
472 { "eighth", tUNUMBER
, 8 },
473 { "ninth", tUNUMBER
, 9 },
474 { "tenth", tUNUMBER
, 10 },
475 { "eleventh", tUNUMBER
, 11 },
476 { "twelfth", tUNUMBER
, 12 },
481 /* The timezone table. */
482 /* Some of these are commented out because a time_t can't store a float. */
483 static TABLE
const TimezoneTable
[] = {
484 { "gmt", tZONE
, HOUR
( 0) }, /* Greenwich Mean */
485 { "ut", tZONE
, HOUR
( 0) }, /* Universal (Coordinated) */
486 { "utc", tZONE
, HOUR
( 0) },
487 { "wet", tZONE
, HOUR
( 0) }, /* Western European */
488 { "bst", tDAYZONE
, HOUR
( 0) }, /* British Summer */
489 { "wat", tZONE
, HOUR
( 1) }, /* West Africa */
490 { "at", tZONE
, HOUR
( 2) }, /* Azores */
492 /* For completeness. BST is also British Summer, and GST is
493 * also Guam Standard. */
494 { "bst", tZONE
, HOUR
( 3) }, /* Brazil Standard */
495 { "gst", tZONE
, HOUR
( 3) }, /* Greenland Standard */
498 { "nft", tZONE
, HOUR
(3.5) }, /* Newfoundland */
499 { "nst", tZONE
, HOUR
(3.5) }, /* Newfoundland Standard */
500 { "ndt", tDAYZONE
, HOUR
(3.5) }, /* Newfoundland Daylight */
502 { "ast", tZONE
, HOUR
( 4) }, /* Atlantic Standard */
503 { "adt", tDAYZONE
, HOUR
( 4) }, /* Atlantic Daylight */
504 { "est", tZONE
, HOUR
( 5) }, /* Eastern Standard */
505 { "edt", tDAYZONE
, HOUR
( 5) }, /* Eastern Daylight */
506 { "cst", tZONE
, HOUR
( 6) }, /* Central Standard */
507 { "cdt", tDAYZONE
, HOUR
( 6) }, /* Central Daylight */
508 { "mst", tZONE
, HOUR
( 7) }, /* Mountain Standard */
509 { "mdt", tDAYZONE
, HOUR
( 7) }, /* Mountain Daylight */
510 { "pst", tZONE
, HOUR
( 8) }, /* Pacific Standard */
511 { "pdt", tDAYZONE
, HOUR
( 8) }, /* Pacific Daylight */
512 { "yst", tZONE
, HOUR
( 9) }, /* Yukon Standard */
513 { "ydt", tDAYZONE
, HOUR
( 9) }, /* Yukon Daylight */
514 { "hst", tZONE
, HOUR
(10) }, /* Hawaii Standard */
515 { "hdt", tDAYZONE
, HOUR
(10) }, /* Hawaii Daylight */
516 { "cat", tZONE
, HOUR
(10) }, /* Central Alaska */
517 { "ahst", tZONE
, HOUR
(10) }, /* Alaska-Hawaii Standard */
518 { "nt", tZONE
, HOUR
(11) }, /* Nome */
519 { "idlw", tZONE
, HOUR
(12) }, /* International Date Line West */
520 { "cet", tZONE
, -HOUR
(1) }, /* Central European */
521 { "met", tZONE
, -HOUR
(1) }, /* Middle European */
522 { "mewt", tZONE
, -HOUR
(1) }, /* Middle European Winter */
523 { "mest", tDAYZONE
, -HOUR
(1) }, /* Middle European Summer */
524 { "swt", tZONE
, -HOUR
(1) }, /* Swedish Winter */
525 { "sst", tDAYZONE
, -HOUR
(1) }, /* Swedish Summer */
526 { "fwt", tZONE
, -HOUR
(1) }, /* French Winter */
527 { "fst", tDAYZONE
, -HOUR
(1) }, /* French Summer */
528 { "eet", tZONE
, -HOUR
(2) }, /* Eastern Europe, USSR Zone 1 */
529 { "bt", tZONE
, -HOUR
(3) }, /* Baghdad, USSR Zone 2 */
531 { "it", tZONE
, -HOUR
(3.5) },/* Iran */
533 { "zp4", tZONE
, -HOUR
(4) }, /* USSR Zone 3 */
534 { "zp5", tZONE
, -HOUR
(5) }, /* USSR Zone 4 */
536 { "ist", tZONE
, -HOUR
(5.5) },/* Indian Standard */
538 { "zp6", tZONE
, -HOUR
(6) }, /* USSR Zone 5 */
540 /* For completeness. NST is also Newfoundland Stanard, and SST is
541 * also Swedish Summer. */
542 { "nst", tZONE
, -HOUR
(6.5) },/* North Sumatra */
543 { "sst", tZONE
, -HOUR
(7) }, /* South Sumatra, USSR Zone 6 */
545 { "wast", tZONE
, -HOUR
(7) }, /* West Australian Standard */
546 { "wadt", tDAYZONE
, -HOUR
(7) }, /* West Australian Daylight */
548 { "jt", tZONE
, -HOUR
(7.5) },/* Java (3pm in Cronusland!) */
550 { "cct", tZONE
, -HOUR
(8) }, /* China Coast, USSR Zone 7 */
551 { "jst", tZONE
, -HOUR
(9) }, /* Japan Standard, USSR Zone 8 */
553 { "cast", tZONE
, -HOUR
(9.5) },/* Central Australian Standard */
554 { "cadt", tDAYZONE
, -HOUR
(9.5) },/* Central Australian Daylight */
556 { "east", tZONE
, -HOUR
(10) }, /* Eastern Australian Standard */
557 { "eadt", tDAYZONE
, -HOUR
(10) }, /* Eastern Australian Daylight */
558 { "gst", tZONE
, -HOUR
(10) }, /* Guam Standard, USSR Zone 9 */
559 { "nzt", tZONE
, -HOUR
(12) }, /* New Zealand */
560 { "nzst", tZONE
, -HOUR
(12) }, /* New Zealand Standard */
561 { "nzdt", tDAYZONE
, -HOUR
(12) }, /* New Zealand Daylight */
562 { "idle", tZONE
, -HOUR
(12) }, /* International Date Line East */
566 /* Military timezone table. */
567 static TABLE
const MilitaryTable
[] = {
568 { "a", tZONE
, HOUR
( 1) },
569 { "b", tZONE
, HOUR
( 2) },
570 { "c", tZONE
, HOUR
( 3) },
571 { "d", tZONE
, HOUR
( 4) },
572 { "e", tZONE
, HOUR
( 5) },
573 { "f", tZONE
, HOUR
( 6) },
574 { "g", tZONE
, HOUR
( 7) },
575 { "h", tZONE
, HOUR
( 8) },
576 { "i", tZONE
, HOUR
( 9) },
577 { "k", tZONE
, HOUR
( 10) },
578 { "l", tZONE
, HOUR
( 11) },
579 { "m", tZONE
, HOUR
( 12) },
580 { "n", tZONE
, HOUR
(- 1) },
581 { "o", tZONE
, HOUR
(- 2) },
582 { "p", tZONE
, HOUR
(- 3) },
583 { "q", tZONE
, HOUR
(- 4) },
584 { "r", tZONE
, HOUR
(- 5) },
585 { "s", tZONE
, HOUR
(- 6) },
586 { "t", tZONE
, HOUR
(- 7) },
587 { "u", tZONE
, HOUR
(- 8) },
588 { "v", tZONE
, HOUR
(- 9) },
589 { "w", tZONE
, HOUR
(-10) },
590 { "x", tZONE
, HOUR
(-11) },
591 { "y", tZONE
, HOUR
(-12) },
592 { "z", tZONE
, HOUR
( 0) },
609 ToSeconds
(Hours
, Minutes
, Seconds
, Meridian
)
615 if
(Minutes
< 0 || Minutes
> 59 || Seconds
< 0 || Seconds
> 59)
619 if
(Hours
< 0 || Hours
> 23)
621 return
(Hours
* 60L + Minutes
) * 60L + Seconds
;
623 if
(Hours
< 1 || Hours
> 12)
625 return
(Hours
* 60L + Minutes
) * 60L + Seconds
;
627 if
(Hours
< 1 || Hours
> 12)
629 return
((Hours
+ 12) * 60L + Minutes
) * 60L + Seconds
;
636 Convert
(Month
, Day
, Year
, Hours
, Minutes
, Seconds
, Meridian
, DSTmode
)
646 static int DaysInMonth
[12] = {
647 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
657 DaysInMonth
[1] = Year %
4 == 0 && (Year %
100 != 0 || Year %
400 == 0)
659 if
(Year
< EPOCH || Year
> 1999
660 || Month
< 1 || Month
> 12
661 /* Lint fluff: "conversion from long may lose accuracy" */
662 || Day
< 1 || Day
> DaysInMonth
[(int)--Month
])
665 for
(Julian
= Day
- 1, i
= 0; i
< Month
; i
++)
666 Julian
+= DaysInMonth
[i
];
667 for
(i
= EPOCH
; i
< Year
; i
++)
668 Julian
+= 365 + (i %
4 == 0);
669 Julian
*= SECSPERDAY
;
670 Julian
+= yyTimezone
* 60L;
671 if
((tod
= ToSeconds
(Hours
, Minutes
, Seconds
, Meridian
)) < 0)
675 ||
(DSTmode
== DSTmaybe
&& localtime
(&Julian
)->tm_isdst
))
682 DSTcorrect
(Start
, Future
)
689 StartDay
= (localtime
(&Start
)->tm_hour
+ 1) %
24;
690 FutureDay
= (localtime
(&Future
)->tm_hour
+ 1) %
24;
691 return
(Future
- Start
) + (StartDay
- FutureDay
) * 60L * 60L;
696 RelativeDate
(Start
, DayOrdinal
, DayNumber
)
705 tm
= localtime
(&now
);
706 now
+= SECSPERDAY
* ((DayNumber
- tm
->tm_wday
+ 7) %
7);
707 now
+= 7 * SECSPERDAY
* (DayOrdinal
<= 0 ? DayOrdinal
: DayOrdinal
- 1);
708 return DSTcorrect
(Start
, now
);
713 RelativeMonth
(Start
, RelMonth
)
723 tm
= localtime
(&Start
);
724 Month
= 12 * tm
->tm_year
+ tm
->tm_mon
+ RelMonth
;
726 Month
= Month %
12 + 1;
727 return DSTcorrect
(Start
,
728 Convert
(Month
, (time_t)tm
->tm_mday
, Year
,
729 (time_t)tm
->tm_hour
, (time_t)tm
->tm_min
, (time_t)tm
->tm_sec
,
740 register
const TABLE
*tp
;
744 /* Make it lowercase. */
745 for
(p
= buff
; *p
; p
++)
749 if
(strcmp
(buff
, "am") == 0 || strcmp
(buff
, "a.m.") == 0) {
750 yylval.Meridian
= MERam
;
753 if
(strcmp
(buff
, "pm") == 0 || strcmp
(buff
, "p.m.") == 0) {
754 yylval.Meridian
= MERpm
;
758 /* See if we have an abbreviation for a month. */
759 if
(strlen
(buff
) == 3)
761 else if
(strlen
(buff
) == 4 && buff
[3] == '.') {
768 for
(tp
= MonthDayTable
; tp
->name
; tp
++) {
770 if
(strncmp
(buff
, tp
->name
, 3) == 0) {
771 yylval.Number
= tp
->value
;
775 else if
(strcmp
(buff
, tp
->name
) == 0) {
776 yylval.Number
= tp
->value
;
781 for
(tp
= TimezoneTable
; tp
->name
; tp
++)
782 if
(strcmp
(buff
, tp
->name
) == 0) {
783 yylval.Number
= tp
->value
;
787 if
(strcmp
(buff
, "dst") == 0)
790 for
(tp
= UnitsTable
; tp
->name
; tp
++)
791 if
(strcmp
(buff
, tp
->name
) == 0) {
792 yylval.Number
= tp
->value
;
796 /* Strip off any plural and try the units table again. */
797 i
= strlen
(buff
) - 1;
798 if
(buff
[i
] == 's') {
800 for
(tp
= UnitsTable
; tp
->name
; tp
++)
801 if
(strcmp
(buff
, tp
->name
) == 0) {
802 yylval.Number
= tp
->value
;
805 buff
[i
] = 's'; /* Put back for "this" in OtherTable. */
808 for
(tp
= OtherTable
; tp
->name
; tp
++)
809 if
(strcmp
(buff
, tp
->name
) == 0) {
810 yylval.Number
= tp
->value
;
814 /* Military timezones. */
815 if
(buff
[1] == '\0' && isalpha
(*buff
)) {
816 for
(tp
= MilitaryTable
; tp
->name
; tp
++)
817 if
(strcmp
(buff
, tp
->name
) == 0) {
818 yylval.Number
= tp
->value
;
823 /* Drop out any periods and try the timezone table again. */
824 for
(i
= 0, p
= q
= buff
; *q
; q
++)
831 for
(tp
= TimezoneTable
; tp
->name
; tp
++)
832 if
(strcmp
(buff
, tp
->name
) == 0) {
833 yylval.Number
= tp
->value
;
851 while
(isspace
(*yyInput
))
854 if
(isdigit
(c
= *yyInput
) || c
== '-' || c
== '+') {
855 if
(c
== '-' || c
== '+') {
856 sign
= c
== '-' ?
-1 : 1;
857 if
(!isdigit
(*++yyInput
))
858 /* skip the '-' sign */
863 for
(yylval.Number
= 0; isdigit
(c
= *yyInput
++); )
864 yylval.Number
= 10 * yylval.Number
+ c
- '0';
867 yylval.Number
= -yylval.Number
;
868 return sign ? tSNUMBER
: tUNUMBER
;
871 for
(p
= buff
; isalpha
(c
= *yyInput
++) || c
== '.'; )
872 if
(p
< &buff
[sizeof buff
- 1])
876 return LookupWord
(buff
);
894 #define TM_YEAR_ORIGIN 1900
896 /* Yield A - B, measured in seconds. */
901 int ay
= a
->tm_year
+ (TM_YEAR_ORIGIN
- 1);
902 int by
= b
->tm_year
+ (TM_YEAR_ORIGIN
- 1);
907 /* difference in day of year */
908 a
->tm_yday
- b
->tm_yday
909 /* + intervening leap days */
910 + ((ay
>> 2) - (by
>> 2))
912 + ((ay
/100 >> 2) - (by
/100 >> 2))
913 /* + difference in years * 365 */
914 + (time_t)(ay
-by
) * 365
915 )*24 + (a
->tm_hour
- b
->tm_hour
)
916 )*60 + (a
->tm_min
- b
->tm_min
)
917 )*60 + (a
->tm_sec
- b
->tm_sec
);
933 (void)time
(&ftz.time
);
935 if
(! (tm
= gmtime
(&ftz.time
)))
937 gmt
= *tm
; /* Make a copy, in case localtime modifies *tm. */
938 ftz.timezone
= difftm
(&gmt
, localtime
(&ftz.time
)) / 60;
941 tm
= localtime
(&now
->time
);
942 yyYear
= tm
->tm_year
;
943 yyMonth
= tm
->tm_mon
+ 1;
945 yyTimezone
= now
->timezone
;
946 yyDSTmode
= DSTmaybe
;
960 || yyHaveTime
> 1 || yyHaveZone
> 1 || yyHaveDate
> 1 || yyHaveDay
> 1)
963 if
(yyHaveDate || yyHaveTime || yyHaveDay
) {
964 Start
= Convert
(yyMonth
, yyDay
, yyYear
, yyHour
, yyMinutes
, yySeconds
,
965 yyMeridian
, yyDSTmode
);
972 Start
-= ((tm
->tm_hour
* 60L + tm
->tm_min
) * 60L) + tm
->tm_sec
;
975 Start
+= yyRelSeconds
;
976 Start
+= RelativeMonth
(Start
, yyRelMonth
);
978 if
(yyHaveDay
&& !yyHaveDate
) {
979 tod
= RelativeDate
(Start
, yyDayOrdinal
, yyDayNumber
);
983 /* Have to do *something* with a legitimate -1 so it's distinguishable
984 * from the error return value. (Alternately could set errno on error.) */
985 return Start
== -1 ?
0 : Start
;
999 (void)printf
("Enter date, or blank line to exit.\n\t> ");
1000 (void)fflush
(stdout
);
1001 while
(gets
(buff
) && buff
[0]) {
1002 d
= get_date
(buff
, (struct timeb
*)NULL
);
1004 (void)printf
("Bad format - couldn't convert.\n");
1006 (void)printf
("%s", ctime
(&d
));
1007 (void)printf
("\t> ");
1008 (void)fflush
(stdout
);
1013 #endif /* defined(TEST) */