jchvr@ihlpg.UUCP (VanRietschote) (04/29/86)
# cut here file=d2d1.c /* * D2D * * APT date to date converter * */ #include <stdio.h> #include <ctype.h> #include <time.h> #include <string.h> #undef NULL; #define NULL 0 #define EOS 0 #define FALSE 0 #define TRUE 1 #define DECENIUM 1980 #define MONDAY 0 #define TUESDAY 1 #define WEDNESDAY 2 #define THURSDAY 3 #define FRIDAY 4 #define SATURDAY 5 #define SUNDAY 6 int ERROR ; /* global error number */ /* 0=okay */ /* 1=err in inf */ /* 2=err in in */ /* 3=err in outf*/ int day_month[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 }; static char *monthnames[] = { "??", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???", }; static char *daynames[] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "???", }; char *INFORMAT = "-%y%m%d"; char *OUTFORMAT = "+%a %h %d 19%y%n"; int year; int month; int day; int week; int weekday; char line[100]; char word[10]; char *valptr; char *informat; char *outformat; char *formptr; char *OUT; char TEMP[512]; /* * dotextline processes the inputstring * */ dotextline(text) char *text; { valptr = text; formptr = informat + 1; year = month = day = week = weekday = -1; while ((*valptr != '\0') && (*formptr != '\0')) { while ((*valptr == *formptr) && (*formptr !='%')) { valptr++; formptr++; } if (*formptr == '%') { if ((do_in_command())) { print_inform_error(text); return(TRUE); } } else { print_inform_error(text); return(TRUE); } } if ((*valptr != '\0') || (*formptr != '\0')) { print_inform_error(text); return(TRUE); } print_date(); return(FALSE); } /* * * error during input processing * */ print_inform_error(text) char *text; { ERROR=1; /* bad inf */ *valptr = '\0'; return(1); } /* * * do all input % commands * */ do_in_command() { int length; int status; formptr++; length = (is_digit(*formptr)) ? (*formptr++ - '0') : -1; switch (*formptr++) { case 'd' : status = getval(&day,0,31,rlength(2,length)); break; case 'm' : status = getval(&month,1,12,rlength(2,length)); break; case 'h' : status = getmonthname(rlength(3,length)); break; case 'y' : status = getval(&year,00,99,rlength(2,length)); year += 1900; break; case 'j' : status = getval(&week,001,953,rlength(3,length)); break; case 'w' : status = getval(&weekday,0,6,rlength(1,length)); break; case 'a' : status = getweekdayname(rlength(3,length)); break; case '.' : valptr++; status = 0; break; case '*' : while (*valptr && (*formptr != *valptr++)) status = 0; formptr++; break; case '%' : status = (*valptr++ == *formptr++) ? FALSE : TRUE; break; default : status = TRUE; } return (status); } /* * Get current date from UNIX * */ do_date() { int tvec[2]; struct tm *localtime(); struct tm *p; time(tvec); p = localtime(tvec); year = p -> tm_year + 1900; month = p -> tm_mon + 1; day = p -> tm_mday; } /* * output processing of the date * */ print_date() { if ((year == -1) && (month == -1) && (day == -1) && (week != -1) && (weekday != -1)) { weekday = (weekday == 0) ? 6 : weekday-1; proces_week(week,weekday); } else { if ((year != -1) && (month != -1) && (day != -1)) { proces_date(year,month,day); } else { ERROR=2; /* bad in */ return(TRUE); } } formptr = outformat + 1; while (*formptr != '\0') { if (*formptr == '%') { if (do_out_command()) { ERROR=3; /* bad outf */ return(TRUE); } } else { sprintf(TEMP,"%c",*formptr++); strcat(OUT,TEMP); } } } do_out_command() { int length; int status; formptr++; status = 0; length = (is_digit(*formptr)) ? (*formptr++ -'0') : -1; switch(*formptr++) { case 'd' : status = putval(day,rlength(2,length)); break; case 'm' : status = putval(month,rlength(2,length)); break; case 'h' : status = putstr(monthnames[month], rlength(3,length)); break; case 'y' : year = year - ((year / 100) * 100 ); status = putval(year,rlength(2,length)); break; case 'j' : status = putval(week,rlength(2,length)); break; case 'w' : status = putval(weekday,rlength(2,length)); break; case 'a' : status = putstr(daynames[weekday], rlength(3,length)); break; case 'n' : strcat(OUT,"\n"); break; case 't' : strcat(OUT,"\t"); break; case '%' : strcat(OUT,"%"); break; default : status = TRUE; } return(status); } /* * determine the weeknumber and weekday * for the given year,month and day * */ proces_date(year,month,day) int year; int month; int day; { int temp; int week_no; week_no = get_weeknumber(year,month,day); temp = (year - (10 * (year / 10))); if ((month == 1) && ((day == 1) || (day == 2))) { if ((day == 2) && (dayofweek(year,month,day) == SUNDAY)) { year += -1; week_no = get_weeknumber(year,12,31); temp += -1; } else { if ((day == 1) && ((dayofweek(year,month,day) == SATURDAY) || (dayofweek(year,month,day) == SUNDAY))) { year += -1; week_no = get_weeknumber(year,12,31); temp += -1; } } } if ((week_no >= 53) && (dayofweek(year,12,31) < FRIDAY)) { temp++; week_no = 1; } week = temp * 100 + week_no; weekday = dayofweek(year,month,day); } /* * * determine the weeknumber without under- & * overflow detection */ get_weeknumber(year,month,day) int year; int month; int day; { int i; int week_no; int no_days; int leapyear; int rest; leapyear = ((year%4) == 0) && (((year%400) == 0) || (year%100 != 0)); no_days = 0; for (i=1; i < month; i++) { no_days += ((i == 2 && leapyear) ? 29 : day_month[i]); } no_days += (day - 1); week_no = (no_days / 7); rest = no_days - (week_no * 7); week_no += 1; if (dayofweek(year,1,1) > FRIDAY) week_no += -1; if ((dayofweek(year,month,day) -rest) <= MONDAY) week_no +=1; return(week_no); } /* * * determine the date (year,month and day) * from a given weeknumver and weekday * */ proces_week(week,weekday) int week; int weekday; { int leapyear; int mark; year = DECENIUM + (week / 100); week = week - (week / 100) * 100; leapyear = ((year %4 == 0) && (((year %400) == 0) || (year%100 != 0))); day = (week - 1) * 7 + weekday - dayofweek(year,1,1); if (day < 0) { month = 12; year--; day = day + 32; } else { for (month = 1; day > 0; month++) { day -= ((month == 2 && leapyear) ? 29 : day_month[month]); } month--; day += day_month[month] +1; month = (month == 0) ? 1 : month; } mark = FALSE; if (day > day_month[month]) { day -= day_month[month++]; if (month > 12) { month = 1; year++; mark = TRUE; } } if ((mark == TRUE) && (month == 1) && (dayofweek(year,month,day) <= FRIDAY)) { return(TRUE); } return(FALSE); } /* * determine the weekday from a given date * day of the week : Sunday = 6, Monday = 0 * */ dayofweek(year,month,day) int year; int month; int day; { register int yearfactor; int dow; yearfactor = year + (month - 14)/12; dow = (( (13 * (month + 10 - (month + 10)/13*12) -1)/5 + day + 77 + 5 * (yearfactor % 100)/4 + yearfactor / 400 - yearfactor / 100 * 2) % 7); return ( (dow == 0) ? 6 : --dow); } /* * * read the monthname from input * */ getmonthname(length) int length; { int l; getstr(length); for (month=1; month<13; month++) { for (l=0; ((l<length) && (word[l] == monthnames[month][l])); l++); if (l == length) break; } return ((month == 13) ? TRUE : FALSE); } /* * * read the weekday from input * */ getweekdayname(length) int length; { int l; getstr(length); for (weekday = 0; (weekday <=7); weekday++) { for (l = 0; ((l<length) && (word[l] == daynames[weekday][l])); l++); if (l == length) break; } if (weekday == 8) return(TRUE); weekday = ++weekday%7; return (FALSE); } /* * return 1e param value if 2nd = -1 * else 2nd param. * */ rlength(p1,p2) int p1; int p2; { return( (p2 == -1) ? p1 : p2); } /* * * Read text to global line[]. * */ getline() { register char *t; return (gets(line) == NULL); } /* * * read a value from the inputstring * given a low and high bound * given a max. length of the number * given a following delimite * */ getval(value,low,high,length) int *value; int low; int high; int length; { register int i; register int temp; if (*valptr == '\0') return(TRUE); while (*valptr && (*valptr == ' ')) *valptr++; for (*value = i = 0;((i < length) && (is_digit(*valptr))); i++) { temp = *valptr++ - '0'; if (temp < 0 || temp > 9) return(TRUE); *value = (*value * 10) + temp; } return((*value >= low && *value <= high) ? FALSE : TRUE); } /* * read a string of a given length * */ getstr(length) int length; { int i; for (i=0; i < length ; i++) { word[i] = *valptr++; } word[i]='\0'; } putval(value,length) int value; int length; { char *form = "%02d"; form[2] = length + '0'; sprintf(TEMP,form,value); strcat(OUT,TEMP); return(0); } putstr(string,length) char *string; int length; { char *form = "%3s"; form[1] = length + '0'; sprintf(TEMP,form,string); strcat(OUT,TEMP); return(0); } is_digit(digit) char digit; { return (((digit < '0') || (digit > '9')) ? FALSE : digit); } /* ETERNAL CALLABLE ROUTINES */ int d2d(inf,in,outf,out) char *inf; /* informat must start with - */ char *in; /* instring with format as in inf */ char *outf; /* outformat must start with +*/ char *out; /* will hold output must be large enough */ /* return ERROR = 0 if all ok /* ERROR = 1 if error in inf /* ERROR = 2 if error in in /* ERROR = 3 if error in outf */ { ERROR = 0; OUT = out; /* initialize out */ strcpy(OUT,""); informat = inf; outformat = outf; dotextline(in); return(ERROR); }