home *** CD-ROM | disk | FTP | other *** search
- /* @(#)dates.c 1.1 (c) copyright 10/15/86 (Dan Heller) */
-
- #include "mush.h"
-
- /*
- * %02d%02d%02d%02d%02d%s yy mm dd hh mm weekday
- * The standard "date format" stored in the msg data structure.
- */
- char *day_names[] = {
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
- };
- char *month_names[] = { /* imported in pick.c */
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- };
-
- /* Time() returns a string according to criteria:
- * if "now" is 0, then the current time is gotten and used.
- * else, use the time described by now
- * opts points to a string of args which is parsed until an unknown
- * arg is found and opts will point to that upon return.
- * valid args are T (time of day), D (day of week), M (month), Y (year),
- * N (number of day in month -- couldn't think of a better letter).
- */
- char *
- Time(opts, now)
- register char *opts;
- long now;
- {
- static char time_buf[30];
- struct tm *T;
- register char *p = time_buf;
- long x;
-
- if (!opts)
- return NULL;
- if (now)
- x = now;
- else
- (void) time(&x);
- T = localtime(&x);
- for (;; opts++) {
- switch(*opts) {
- case 'T':
- if (ison(glob_flags, MIL_TIME))
- (void) sprintf(p, "%2d:%02d", T->tm_hour, T->tm_min);
- else
- (void) sprintf(p, "%d:%02d", (T->tm_hour) ?
- ((T->tm_hour <= 12) ? T->tm_hour : T->tm_hour - 12) :
- 12, T->tm_min);
- when 'D': case 'W': (void) strcpy(p, day_names[T->tm_wday]);
- when 'M': (void) strcpy(p, month_names[T->tm_mon]);
- when 'y': (void) sprintf(p, "%d", T->tm_year);
- when 'Y': (void) sprintf(p, "19%d", T->tm_year);
- when 'N': (void) sprintf(p, "%d", T->tm_mday);
- otherwise: *--p = 0; return time_buf;
- }
- p += strlen(p);
- *p++ = ' ';
- }
- }
-
- /* parse date and return a string that looks like
- * "%2d%2d%2d%2d%2d%3c", wkday,yr,mo,date,hrs,mins
- * This function is a bunch of scanfs on known date formats. Don't
- * trust the "weekday" name fields because they may not be spelled
- * right, or have the correct punctuation. Figure it out once the
- * year and month and date have been determined.
- */
- char *
- parse_date(p)
- register char *p;
- {
- /* When scanf-ing if month isn't a month, it could be a _long_ string.
- * this is also the static buffer whose address we return.
- */
- static char month[64];
- char Wkday[4];
- int Month = 0, Day = 0, Year = 0, Hours = -1, Mins = -1;
-
- skipspaces(0);
-
- /* Possible combinations that we could have:
- * day_number month_name year_number time timezone ...
- * day_name month_name day_number time year_number
- * day_name month_name day_number year_number time
- * day_name day_number month_name year_number time
- * day_number month_name year_number time
- * day_number month_name year_number time-timezone (day)
- * ^no colon separator
- * day_name month_name day_number time timezone year_number
- * day_number-month_name-year time
- * day_name, day_number-month_name-year time
- * day_number month_name year_number, time "-"
- */
- /* programmer's note -- there are too many scanfs here for some compilers
- * to put them all into one if statement. Use goto's :-(
- */
- if (sscanf(p, "%*s %s %d %d %d:%d", month,&Day,&Year,&Hours,&Mins) == 5)
- goto gotit;
- if (sscanf(p, "%d %s %d %d:%d", &Day,month,&Year,&Hours,&Mins) == 5)
- goto gotit;
- if (sscanf(p, "%*s %s %d %d:%d:%*d %d", month,&Day,&Hours,&Mins,&Year) == 5)
- goto gotit;
- if (sscanf(p, "%*s %d %s %d %d:%d", &Day,month,&Year,&Hours,&Mins) == 5)
- goto gotit;
- if (sscanf(p, "%d %s %d %d:%d", &Day,month,&Year,&Hours,&Mins) == 5)
- goto gotit;
- if (sscanf(p, "%d %s %d %2d%2d", &Day,month,&Year,&Hours,&Mins) == 5)
- goto gotit;
- if (sscanf(p, "%*s %s %d %d:%d:%*d %*s %d",
- month, &Day, &Hours, &Mins, &Year) == 5)
- goto gotit;
- if (sscanf(p, "%*s %s %d %d:%d %*s %d",
- month, &Day, &Hours, &Mins, &Year) == 5)
- goto gotit;
- if (sscanf(p,"%d-%[^-]-%d %d:%d", &Day, month, &Year, &Hours, &Mins) == 5)
- goto gotit;
- if (sscanf(p,"%d %s %d, %d:%d:%*d -",&Day, month, &Year, &Hours, &Mins)== 5)
- goto gotit;
- if (sscanf(p,"%*s %d-%[^-]-%d %d:%d",&Day, month, &Year, &Hours, &Mins)== 5)
- goto gotit;
- goto didnt_getit;
- gotit:
- if (Year > 99)
- Year %= 100;
- if ((Month = month_to_n(month)) == -1) {
- print("bad month: %s\n", p);
- return NULL;
- }
- {
- static int mtbl[]={0,31,59,90,120,151,181,212,243,273,304,334};
- int days_ctr;
-
- days_ctr = ((Year * 365) + ((Year + 3) / 4) + mtbl[Month-1] + Day + 6);
- if (Month > 2 && (Year % 4 == 0))
- days_ctr++;
- (void) (sprintf(Wkday, "%.3s", day_names[days_ctr % 7]));
- }
- return sprintf(month, "%02d%02d%02d%02d%02d%s",
- Year, Month, Day, Hours, Mins, Wkday);
- didnt_getit:
- if (ison(glob_flags, WARNING))
- print("Unknown date format: %s\n", p);
- return NULL;
- }
-
- /* pass a string in the standard date format, put into string.
- * return values in buffers provided they are not null.
- */
- char *
- date_to_string(Date, Yr, Mon, Day, Wkday, Tm, ret_buf)
- char *Date, *Yr, *Mon, *Day, *Wkday, *Tm, *ret_buf;
- {
- unsigned int days_ctr;
- int yr, mon, day, hr, mins;
- char a_or_p, *p = ret_buf;
-
- (void) sscanf(Date, "%2d%2d%2d%2d%2d%3c",
- &yr, &mon, &day, &hr, &mins, Wkday);
- Wkday[3] = 0;
- a_or_p = (hr < 12)? 'a': 'p';
-
- (void) sprintf(Yr, "19%d", yr);
- (void) sprintf(Day, "%d", day);
- (void) strcpy(Mon, month_names[mon-1]);
- p += strlen(sprintf(p, "%s %2.d, ", month_names[mon-1], day));
- if (ison(glob_flags, MIL_TIME))
- (void) sprintf(p, "%2d:%02d",hr,mins);
- else
- (void) sprintf(p, "%2.d:%02d%cm",
- (hr)? (hr <= 12)? hr: hr - 12: 12, mins, a_or_p);
- (void) strcpy(Tm, p);
- return ret_buf;
- }
-
- /* pass a string in the internal mush date format.
- * return pointer to static buffer holding ctime-format date.
- */
- char *
- date_to_ctime(Date)
- char *Date;
- {
- static char ret_buf[32];
- char Wkday[4];
- int yr, mon, day, hr, mins;
-
- (void) sscanf(Date, "%2d%2d%2d%2d%2d%3c",
- &yr, &mon, &day, &hr, &mins, Wkday);
-
- (void) sprintf(ret_buf, "%.3s %.3s %2.d %02d:%02d:00 19%d\n",
- Wkday, month_names[mon-1], day, hr, mins, yr);
-
- return ret_buf;
- }
-
- /*
- * Build a date string according to the specification in the RFC for Date:
- */
- char *
- rfc_date(buf)
- char buf[];
- {
- struct tm *T;
- #ifdef SYSV
- long x;
- extern char *tzname[];
- char *tz;
-
- (void) time(&x);
- T = localtime(&x);
- tz = tzname[T->tm_isdst];
- #else /* SYSV */
- #ifdef BSD
- extern char *timezone();
- struct timeval mytime;
- struct timezone myzone;
- char *tz;
-
- (void) gettimeofday(&mytime, &myzone);
- T = localtime(&mytime.tv_sec);
- tz = timezone(myzone.tz_minuteswest, (T->tm_isdst && myzone.tz_dsttime));
- #else
- char *tz = "";
- #endif /* BSD */
- #endif /* !SYSV */
-
- return sprintf(buf, "%s, %d %s %d %02d:%02d:%02d %s",
- day_names[T->tm_wday], /* day name */
- T->tm_mday, /* day of the month */
- month_names[T->tm_mon], /* month name */
- T->tm_year, /* year number */
- T->tm_hour, /* hours (24hr) */
- T->tm_min, T->tm_sec, /* mins/secs */
- tz); /* timezone */
- }
-
- #define JAN 1
- #define FEB 2
- #define MAR 3
- #define APR 4
- #define MAY 5
- #define JUN 6
- #define JUL 7
- #define AUG 8
- #define SEP 9
- #define OCT 10
- #define NOV 11
- #define DEC 12
-
- /* stolen direct from ELM */
- month_to_n(name)
- register char *name;
- {
- /** return the month number given the month name... **/
-
- register char ch;
-
- switch (lower(*name)) {
- case 'a' : if ((ch = lower(name[1])) == 'p')
- return(APR);
- else if (ch == 'u')
- return(AUG);
- else return(-1); /* error! */
- case 'd' : return(DEC);
- case 'f' : return(FEB);
- case 'j' : if ((ch = lower(name[1])) == 'a')
- return(JAN);
- else if (ch == 'u') {
- if ((ch = lower(name[2])) == 'n')
- return(JUN);
- else if (ch == 'l')
- return(JUL);
- else return(-1); /* error! */
- }
- else return(-1); /* error */
- case 'm' : if ((ch = lower(name[2])) == 'r')
- return(MAR);
- else if (ch == 'y')
- return(MAY);
- else return(-1); /* error! */
- case 'n' : return(NOV);
- case 'o' : return(OCT);
- case 's' : return(SEP);
- default : return(-1);
- }
- }
-