]>
diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/miscellany/mem/promptdate.c
2 static char Id
[] = "$Id: promptdate.c,v 1.2 1996/02/09 17:38:07 jromine Exp $";
11 ** prompt user for a date specification which can be quite minimal
12 ** and print it in a form suitable for parsing by MH
18 "Jan","Feb","Mar","Apr","May","Jun",
19 "Jul","Aug","Sep","Oct","Nov","Dec"};
21 "Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
24 int monthlen
[2][12] ={
25 31,28,31,30,31,30,31,31,30,31,30,31,
26 31,29,31,30,31,30,31,31,30,31,30,31};
27 char *defaultformat
= "%d %N %y 00:00";
35 extern int optind
; /* defined in getopt */
36 extern char *optarg
; /* defined in getopt */
40 while ((c
= getopt (argc
, argv
, "f:")) != EOF
)
45 defaultformat
= optarg
;
48 fprintf(stderr
, "usage: %s [-f format] [datespec]\n", argv
[0]);
55 finddate(&now
, dayspast
= (int)(secsfr70()/86400L));
57 if (argc
<= 0) /* get from user */
59 if (!promptdate(&then
))
61 printdate(&then
, defaultformat
);
63 else /* get from command line */
65 if (!decodedate(argv
[0], &then
))
67 printdate(&then
, defaultformat
);
81 fprintf(stderr
, "When? ");
82 if (fgets(line
, sizeof(line
), stdin
) == NULL
)
84 fprintf(stderr
, "\n");
87 p
= line
+ strlen (line
) - 1;
90 if (decodedate(line
, when
))
96 int decodedate(line
, when
)
100 ** accept spec for date in several forms
101 ** legal are: sun,mon,tue,wed,thu,fri,sat,today,tomorrow,
102 ** <date><month>,+<relative number of days>
103 ** <month> should be alpha
104 ** upper case accepted too
108 register int i
,targetdate
;
112 when
->tm_year
= now
.tm_year
;
113 when
->tm_mon
= now
.tm_mon
;
114 targetdate
= dayspast
;
115 for (lptr
= line
; isspace(*lptr
); lptr
++)
119 i
= sscanf(lptr
, "%d%3s%d", &when
->tm_mday
, s
, &tem
);
126 when
->tm_mon
= monthofyear(s
);
129 if (when
->tm_mday
!= 0 && when
->tm_mon
!= 0 && daysfr70(when
) < dayspast
)
133 if (when
->tm_mday
!= 0 && when
->tm_mday
< now
.tm_mday
)
135 if (++when
->tm_mon
> 12)
142 return (validate(when
));
146 sscanf(lptr
, "%3s", s
);
148 if ((tem
= dayofweek(s
)) >= 0)
149 targetdate
+= (tem
-= now
.tm_wday
) <= 0 ? tem
+ 7 : tem
;
150 else if (strcmp(s
, "Tom") == 0)
152 else if (strcmp(s
, "Tod") == 0)
157 else if (*lptr
== '+')
159 if (sscanf(++lptr
, "%d", &tem
) == 0 || tem
< 0) /* mistake */
163 else /* mistake by default */
165 finddate(when
, targetdate
);
166 return (when
->tm_mday
!= 0);
171 ** check that a given date and month combination is legal
172 ** datetm->tm_year must hold the year in question
174 register struct tm
*datetm
;
177 return (datetm
->tm_mday
<= monthlen
[leapyear(datetm
->tm_year
)]
178 [datetm
->tm_mon
] && datetm
->tm_mday
> 0);
181 finddate(datetm
, df70
)
183 ** convert days from 1 jan 1970 to a date in struct datetm
186 register struct tm
*datetm
;
188 register struct tm
*tdtm
;
192 longtime
= df70
* 86400L;
193 tdtm
= gmtime(&longtime
);
194 datetm
->tm_yday
= tdtm
->tm_yday
;
195 datetm
->tm_wday
= tdtm
->tm_wday
;
196 datetm
->tm_year
= tdtm
->tm_year
+ 1900;
197 datetm
->tm_mon
= tdtm
->tm_mon
;
198 datetm
->tm_mday
= tdtm
->tm_mday
;
199 datetm
->tm_hour
= tdtm
->tm_hour
;
200 datetm
->tm_min
= tdtm
->tm_min
;
201 datetm
->tm_sec
= tdtm
->tm_sec
;
206 ** convert first character to uppercase
207 ** convert rest of string from uppercase to lower case
213 if ((c
= *s
) != '\0')
214 *s
++ += islower(c
) ? 'A' - 'a' : 0;
215 while ((c
= *s
) != '\0')
216 *s
++ += isupper(c
) ? 'a' - 'A' : 0;
221 ** returns 1 if leapyear 0 otherwise
226 return (((y
% 4) == 0 && (y
% 100) != 0) || (y
% 400) == 0);
231 ** returns the number of days from 1 Jan 1970
232 ** no checking for illegal date at all
234 register struct tm
*datetm
;
236 register int i
, totdays
;
240 for (i
= 1970; i
<= 2050 && i
< datetm
->tm_year
; i
++) /* prevent overflow */
241 totdays
+= 365 + leapyear(i
);
242 for (i
= 0; i
< 12 && i
< datetm
->tm_mon
; i
++)
243 totdays
+= monthlen
[leapyear(datetm
->tm_year
)][i
];
244 totdays
+= datetm
->tm_mday
- 1;
250 ** returns month of year in numeric form when given
251 ** the first three letters
258 for (i
= 12; i
-- && strcmp(s
,mname
[i
]); )
265 ** sunday = 0,...,saturday = 6, nomatch = -1
272 for (i
= 7; i
-- && strcmp(s
,dname
[i
]); )
277 printdate(date
, format
)
279 ** print date in MH acceptable format
280 ** kludge - general formats are not implemented
285 printf("%d %s %d 00:00\n",
286 date
->tm_mday
, mname
[date
->tm_mon
], date
->tm_year
);
291 ** This is system dependent
297 struct tm
*localtime();
299 gettimeofday(&tv
, &tz
);
300 dst
= localtime(&tv
.tv_sec
)->tm_isdst
;
301 return (tv
.tv_sec
- tz
.tz_minuteswest
* 60 + (dst
? 3600 : 0));