|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T d
Length: 10281 (0x2829) Types: TextFile Names: »date.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦this⟧ »EUUGD11/euug-87hel/sec1/elm/src/date.c«
/** date.c **/ /** return the current date and time in a readable format! **/ /** also returns an ARPA RFC-822 format date... **/ /** (C) Copyright 1985, Dave Taylor **/ #include "headers.h" #ifdef BSD # ifndef BSD4.1 # include <sys/time.h> # else # include <time.h> # include <sys/types.h> # include <sys/timeb.h> # endif #else # include <time.h> #endif #include <ctype.h> #ifdef BSD #undef toupper #undef tolower #endif #define MONTHS_IN_YEAR 11 /* 0-11 equals 12 months! */ #define FEB 1 /* 0 = January */ #define DAYS_IN_LEAP_FEB 29 /* leap year only */ #define ampm(n) (n > 12? n - 12 : n) #define am_or_pm(n) (n > 11? (n > 23? "am" : "pm") : "am") #define leapyear(year) ((year % 4 == 0) && (year % 100 != 0)) char *monname[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ""}; char *arpa_dayname[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "" }; char *arpa_monname[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""}; int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, -1}; #ifdef BSD char *timezone(); #else extern char *tzname[]; #endif char *shift_lower(), *strcpy(), *strncpy(); char *get_arpa_date() { /** returns an ARPA standard date. The format for the date according to DARPA document RFC-822 is exemplified by; Mon, 12 Aug 85 6:29:08 MST **/ static char buffer[SLEN]; /* static character buffer */ struct tm *the_time, /* Time structure, see CTIME(3C) */ *localtime(); long junk, /* time in seconds.... */ time(); #ifdef BSD # ifdef BSD4.1 struct timeb loc_time; junk = time(long *) 0); ftime(&loc_time); # else struct timeval time_val; struct timezone time_zone; gettimeofday(&time_val, &time_zone); junk = time_val.tv_sec; # endif #else junk = time((long *) 0); /* this must be here for it to work! */ #endif the_time = localtime(&junk); sprintf(buffer, "%s, %d %s %d %d:%02d:%02d %s", arpa_dayname[the_time->tm_wday], the_time->tm_mday % 32, arpa_monname[the_time->tm_mon], the_time->tm_year % 100, the_time->tm_hour % 24, the_time->tm_min % 61, the_time->tm_sec % 61, #ifdef BSD # ifdef BSD4.1 timezone(time_zone.timezone, the_time->tm_isdst)); # else timezone(time_zone.tz_minuteswest, the_time->tm_isdst)); # endif #else tzname[the_time->tm_isdst]); #endif return( (char *) buffer); } char *full_month(month) char *month; { /** Given a three letter month abbreviation, return the full name of the month. If can't figure it out, just return the given argument. **/ char name[4]; char *shift_lower(); register int i; /** ensure name in correct case... **/ strncpy(name, shift_lower(month), 3); name[0] = toupper(name[0]); /** now simply step through arpa_monname table to find a match **/ for (i=0; i < 12; i++) if (strncmp(name, arpa_monname[i], 3) == 0) return((char *) monname[i]); dprint1(2, "Warning: Couldn't expand monthname %s (full_month)\n", month); return( (char *) month); } days_ahead(days, buffer) int days; char *buffer; { /** return in buffer the date (Day, Mon Day, Year) of the date 'days' days after today. **/ struct tm *the_time, /* Time structure, see CTIME(3C) */ *localtime(); long junk, /* time in seconds.... */ time(); junk = time((long *) 0); /* this must be here for it to work! */ the_time = localtime(&junk); /* increment the day of the week */ the_time->tm_wday = (the_time->tm_wday + days) % 7; /* the day of the month... */ the_time->tm_mday += days; if (the_time->tm_mday > days_in_month[the_time->tm_mon]) { if (the_time->tm_mon == FEB && leapyear(the_time->tm_year)) { if (the_time->tm_mday > DAYS_IN_LEAP_FEB) { the_time->tm_mday -= days_in_month[the_time->tm_mon]; the_time->tm_mon += 1; } } else { the_time->tm_mday -= days_in_month[the_time->tm_mon]; the_time->tm_mon += 1; } } /* check the month of the year */ if (the_time->tm_mon > MONTHS_IN_YEAR) { the_time->tm_mon -= MONTHS_IN_YEAR; the_time->tm_year += 1; } /* now, finally, build the actual date string */ sprintf(buffer, "%s, %d %s %d", arpa_dayname[the_time->tm_wday], the_time->tm_mday % 32, arpa_monname[the_time->tm_mon], the_time->tm_year % 100); } int valid_date(day, mon, year) char *day, *mon, *year; { /** Validate the given date - returns TRUE iff the date handed is reasonable and valid. Ignore month param, okay? **/ register int daynum, yearnum; daynum = atoi(day); yearnum = atoi(year); if (daynum < 1 || daynum > 31) { dprint1(3, "Error: day %d is obviously wrong! (valid_date)\n", daynum); return(0); } if (yearnum < 1 || (yearnum > 100 && yearnum < 1900) || yearnum > 2000) { dprint1(3, "Error: year %d is obviously wrong! (valid_date)\n", yearnum); return(0); } return(1); } fix_date(entry) struct header_rec *entry; { /** This routine will 'fix' the date entry for the specified message. This consists of 1) adjusting the year to 0-99 and 2) altering time from HH:MM:SS to HH:MM am|pm **/ if (atoi(entry->year) > 99) sprintf(entry->year,"%d", atoi(entry->year) - 1900); fix_time(entry->time); } fix_time(timestring) char *timestring; { /** Timestring in format HH:MM:SS (24 hour time). This routine will fix it to display as: HH:MM [am|pm] **/ int hour, minute; sscanf(timestring, "%d:%d", &hour, &minute); if (hour < 1 || hour == 24) sprintf(timestring, "12:%2.2d (midnight)", minute); else if (hour < 12) sprintf(timestring, "%d:%2.2d am", hour, minute); else if (hour == 12) sprintf(timestring, "%d:%2.2d (noon)", hour, minute); else if (hour < 24) sprintf(timestring, "%d:%2.2d pm", hour-12, minute); } int compare_dates(rec1, rec2) struct header_rec *rec1, *rec2; { /** This function works similarly to the "strcmp" function, but has lots of knowledge about the internal date format... Apologies to those who "know a better way"... **/ int month1, day1, year1, hour1, minute1, month2, day2, year2, hour2, minute2; year1 = atoi(rec1->year); year2 = atoi(rec2->year); if (year1 != year2) return( year1 - year2 ); /* And HERE's where the performance of this sort dies... */ month1 = month_number(rec1->month); /* retch... gag.... */ month2 = month_number(rec2->month); /* puke... */ if (month1 == -1) dprint1(2,"month_number failed on month '%s'\n", rec1->month); if (month2 == -1) dprint1(2,"month_number failed on month '%s'\n", rec2->month); if (month1 != month2) return( month1 - month2 ); /* back and cruisin' now, though... */ day1 = atoi(rec1->day); /* unfortunately, 2 is greater than 19 */ day2 = atoi(rec2->day); /* on a dump string-only compare... */ if (day1 != day2) return( day1 - day2 ); /* we're really slowing down now... */ minute1 = minute2 = -1; sscanf(rec1->time, "%d:%d", &hour1, &minute1); sscanf(rec2->time, "%d:%d", &hour2, &minute2); /* did we get the time? If not, try again */ if (minute1 < 0) sscanf(rec1->time, "%2d%2d", &hour1, &minute1); if (minute2 < 0) sscanf(rec2->time, "%2d%2d", &hour2, &minute2); /** deal with am/pm, if present... **/ if (strlen(rec1->time) > 3) if (rec1->time[strlen(rec1->time)-2] == 'p') hour1 += 12; if (strlen(rec2->time) > 3) if (rec2->time[strlen(rec2->time)-2] == 'p') hour2 += 12; if (hour1 != hour2) return( hour1 - hour2 ); return( minute1 - minute2 ); /* ignore seconds... */ } int compare_parsed_dates(rec1, rec2) struct date_rec rec1, rec2; { /** This function is very similar to the compare_dates function but assumes that the two record structures are already parsed and stored in "date_rec" format. **/ if (rec1.year != rec2.year) return( rec1.year - rec2.year ); if (rec1.month != rec2.month) return( rec1.month - rec2.month ); if (rec1.day != rec2.day) return( rec1.day - rec2.day ); if (rec1.hour != rec2.hour) return( rec1.hour - rec2.hour ); return( rec1.minute - rec2.minute ); /* ignore seconds... */ } int month_number(name) char *name; { /** return the month number given the month name... **/ char ch; switch (tolower(name[0])) { case 'a' : if ((ch = tolower(name[1])) == 'p') return(APRIL); else if (ch == 'u') return(AUGUST); else return(-1); /* error! */ case 'd' : return(DECEMBER); case 'f' : return(FEBRUARY); case 'j' : if ((ch = tolower(name[1])) == 'a') return(JANUARY); else if (ch == 'u') { if ((ch = tolower(name[2])) == 'n') return(JUNE); else if (ch == 'l') return(JULY); else return(-1); /* error! */ } else return(-1); /* error */ case 'm' : if ((ch = tolower(name[2])) == 'r') return(MARCH); else if (ch == 'y') return(MAY); else return(-1); /* error! */ case 'n' : return(NOVEMBER); case 'o' : return(OCTOBER); case 's' : return(SEPTEMBER); default : return(-1); } } #ifdef SITE_HIDING char *get_ctime_date() { /** returns a ctime() format date, but a few minutes in the past...(more cunningness to implement hidden sites) **/ static char buffer[SLEN]; /* static character buffer */ struct tm *the_time, /* Time structure, see CTIME(3C) */ *localtime(); long junk, /* time in seconds.... */ time(); #ifdef BSD struct timeval time_val; struct timezone time_zone; #endif #ifdef BSD gettimeofday(&time_val, &time_zone); junk = time_val.tv_sec; #else junk = time((long *) 0); /* this must be here for it to work! */ #endif the_time = localtime(&junk); sprintf(buffer, "%s %s %d %02d:%02d:%02d %d", arpa_dayname[the_time->tm_wday], arpa_monname[the_time->tm_mon], the_time->tm_mday % 32, min(the_time->tm_hour % 24, (rand() % 24)), min(abs(the_time->tm_min % 61 - (rand() % 60)), (rand() % 60)), min(abs(the_time->tm_sec % 61 - (rand() % 60)), (rand() % 60)), the_time->tm_year % 100 + 1900); return( (char *) buffer); } #endif