home *** CD-ROM | disk | FTP | other *** search
- /* ==( bench/date.c )== */
-
- /* ----------------------------------------------- */
- /* Pro-C Copyright (C) 1988 - 1990 Vestronix Inc. */
- /* Modification to this source is not supported */
- /* by Vestronix Inc. */
- /* All Rights Reserved */
- /* ----------------------------------------------- */
- /* Written PRS 1-Jan-88 */
- /* Modified DM 17-Jan-90 See comments below */
- /* ----------------------------------------------- */
- /* %W% (%H% %T%) */
-
- /*
- * Modifications
- *
- * 22-Apr-90 JH - bug fixes
- * 17-Jan-90 DM - v2.0 Enhancement
- */
-
- #include <stdio.h>
- #include <bench.h>
- #include <time.h>
-
- # define BADDATE "Invalid Date"
- # define BADYEAR "Invalid Year"
- # define BADMONTH "Invalid Month"
- # define BADDAY "Invalid Days"
- # define BADHOUR "Invalid Hours"
- # define BADMINUTE "Invalid Minutes"
- # define BADSECOND "Invalid Seconds"
-
- /*
- * Written - DM, JZ
- *
- * The following date arithmetic routines employ 3 types of date formats.
- * Dates are stored internally as the number of seconds since startyear.
- * Using an unsigned long type, this allows a span of 136 years from
- * startyear to be available in calculations.
- * For calculation purposes, the seconds since Startyear is used.
- * A constant in the form YYMMDDHHNNSS needs to be represented as
- * seconds too. This calculation is determined by the current system date.
- * ie. 1 month from Feb 3 is 28 days but 1 month from Mar 3 is 31 days.
- * The final date format is as a character string (not necessarily null
- * terminated). The string is composed of sets of 2 digits, each of which
- * describes one of year, month, date, hour, minute or second. The specific
- * layout of the string is given by a mask string. The mask string can
- * contain any of Y, M, D, H, N, or S, and must be null terminated. Any
- * other characters are ignored.
- *
- * The types of arithmetic expected are
- * datestring + constant ==> datestring
- * and long + constant ==> datestring.
- * These additions are achieved by converting the datestring and/or constant
- * to a long using the routines dstrtol or contol. The results of
- * these conversions are then added to each other and converted back to a
- * date using ltocon. */
-
-
- /*
- * Static Function Prototypes
- */
- #ifdef ANSI
- static int gpair(char **);
- static void intcat(int, char *);
- #else
- static int gpair();
- static void intcat();
- #endif
-
- /*
- * Additional support function for UNIX
- */
- # ifdef UNIX
- char *itoa(n, str, base)
- int n;
- char *str;
- int base;
- {
- if (base == 10)
- sprintf(str, "%d", n);
- return (str);
- }
- # endif
-
- /*
- * Global Variables
- */
-
- int startyear = 1970;
- extern int day_tab[][13];
-
- static int gpair(cp)
- char **cp;
- {
- register int c, d;
-
- if (**cp == 0)
- return(-1);
- c = (**cp - '0') * 10;
- (*cp)++;
- if (c<0 || c>100)
- return(-2);
- if(**cp == 0)
- return(-3);
- d = **cp - '0';
- (*cp)++;
- if (d<0 || d>9)
- return(-4);
- return (c+d);
- }
-
- /*
- * Catenate the integer num onto the end of buffer
- * ensuring that num is at least 2 digits.
- */
- static void intcat(num, buffer)
- int num;
- char *buffer;
- {
- char pair[3];
-
- if (strlen(itoa(num, pair, 10)) == 1)
- strcat(buffer, "0");
- strcat(buffer, pair);
- }
-
- /*
- * todaystr() modifies a char string passed in to contain todays date
- * in the form of a string of the form "YYYYMMDDHHNNSS"
- */
- void todaystr(tstr)
- char *tstr;
- {
- time_t secs;
- struct tm *tim;
-
- time(&secs);
-
- tim = localtime(&secs);
-
- tim->tm_year += 1900;
-
- sprintf(tstr, "%04d%02d%02d%02d%02d%02d", tim->tm_year, tim->tm_mon+1, tim->tm_mday, tim->tm_hour, tim->tm_min, tim->tm_sec);
-
- return;
- }
-
- /*
- * Converts the constant dtcon to the number of seconds since Jan. 1 of
- * startyear using the constant basedt as the base date for adding dtcon.
- */
- unsigned long contol(dtcon)
- char *dtcon; /* Assumed form of date constant is "YYMMDDHHNNSS" */
- {
- int i;
- int y1, m1, d1, h1, n1, s1;
- int tdyy, tdym;
- unsigned long timbuf = 0L;
- char tdydtstr[15];
- char *tdydtstr_ptr;
-
- if (*dtcon == '\0')
- return (0L);
-
- todaystr(tdydtstr); /* get today's date in YYYYMMDDHHNNSS */
- tdydtstr_ptr = tdydtstr;
- tdyy = gpair(&tdydtstr_ptr); /* pick apart */
- tdyy *= 100;
- tdyy += gpair(&tdydtstr_ptr); /* pick apart */
- tdym = gpair(&tdydtstr_ptr)-1; /* today's date into tdyy and tdym */
-
- y1 = gpair(&dtcon);
- if (y1<0 || y1>99)
- {
- errmsg(BADDATE);
- return(0L);
- }
- m1 = gpair(&dtcon);
- if (m1<0 || m1>99)
- {
- errmsg(BADDATE);
- return(0L);
- }
- d1 = gpair(&dtcon);
- if (d1<0 || d1>99)
- {
- errmsg(BADDATE);
- return(0L);
- }
- h1 = gpair(&dtcon);
- if (h1<0 || h1>99)
- {
- errmsg(BADDATE);
- return(0L);
- }
- n1 = gpair(&dtcon);
- if (n1<0 || n1>99)
- {
- errmsg(BADDATE);
- return(0L);
- }
- s1 = gpair(&dtcon);
- if (s1<0 || s1>99)
- {
- errmsg(BADDATE);
- return(0L);
- }
-
- /* Calculate constant in terms of number of seconds since today's date. */
-
- /* Add the years to the months i.t.o. months */
- /*
- * I don't understand why this calculation was here !!
- *
- m1 += (y1-(startyear%100))*12-1;
- */
- m1 += (y1 * 12);
-
- /* adds month sizes to timbuf for the number of months in constant */
-
- for ( i = tdym; i < tdym+m1; i++)
- timbuf += day_tab[ !((tdyy+i/12)%4) ][ i%12+1 ];
-
- /* Break days down into seconds and add in remaining time in seconds. */
- timbuf += d1;
- timbuf *= 24;
- timbuf += h1;
- timbuf *= 60;
- timbuf += n1;
- timbuf *= 60;
- timbuf += s1;
- return(timbuf);
- }
-
- /*
- * Converts a date string (as formatted by mask) to
- * long integer representing the number of seconds since Jan. 1 1970
- */
- unsigned long dstrtol(dtstring, mask)
- char *dtstring;
- char *mask;
- {
- int i;
- int y=0, m=1, d=1, h=0, n=0, s=0;
- unsigned long timbuf = 0L;
-
- if (*dtstring == '\0')
- return (0L);
-
- /*
- errmsg("dstrtol(): dtsring '%s' mask '%s'", dtstring, mask);
- */
- /*
- * Use mask to put dtstring into y, m, and d.
- * Also, check validity of values.
- */
- while (*mask)
- {
- switch (*mask)
- {
- case 'Y' :
- if (*(mask+3) == 'Y')
- {
- /*
- * 4 Character Year
- */
- y = gpair(&dtstring);
- y *= 100;
- y += gpair(&dtstring);
- mask += 3;
- }
- else if (*(mask+2) == 'Y')
- {
- /*
- * All 2 Character Years are assumed
- * to be 1900 and something
- */
- y = 1900;
- dtstring++;
- y += gpair(&dtstring);
- mask += 2;
- }
- else if (*(mask+1) == 'Y')
- {
- /*
- * All 2 Character Years are assumed
- * to be 1900 and something
- */
- y = 1900;
- y += gpair(&dtstring);
- mask++;
- }
- if (y < startyear)
- {
- errmsg(BADYEAR);
- y = startyear;
- }
- break;
-
- case 'M' :
- m = gpair(&dtstring);
- if (m<1 || m>12)
- {
- errmsg(BADMONTH);
- m = 1;
- }
- if (*(mask+1) == 'M') mask++;
- break;
-
- case 'D' :
- d = gpair(&dtstring);
- if (*(mask+1) == 'D') mask++;
- break;
-
- case 'H' :
- h = gpair(&dtstring);
- if (h < 0 || h > 23)
- {
- errmsg(BADHOUR);
- h = 0;
- }
- if (*(mask+1) == 'H') mask++;
- break;
-
- case 'N' :
- n = gpair(&dtstring);
- if (n < 0 || n > 59)
- {
- errmsg(BADMINUTE);
- n = 0;
- }
- if (*(mask+1) == 'N') mask++;
- break;
-
- case 'S' :
- s = gpair(&dtstring);
- if (s < 0 || s > 59)
- {
- errmsg(BADSECOND);
- s = 0;
- }
- if (*(mask+1) == 'S') mask++;
- break;
- }
- mask++;
- }
- /*
- errmsg("dstrtol() : y %d m %d d %d h %d n %d s %d", y, m, d, h, n, s);
- */
-
- if (d<1 || d > day_tab[ y%4 == 0 ][ m ])
- {
- errmsg(BADDAY);
- d = 1;
- }
-
- /* Convert y, m, and d to time quantity forms for constant. */
- y -= startyear;
- m--;
- /* this messes up compares on dates JH
- d--;
- */
-
- m += y*12; /* Add the number of years in terms of months */
- /*
- errmsg("m %d y %d", m, y);
- */
- for ( i = 0; i < m; i++)
- timbuf += day_tab[ !((startyear+i/12)%4) ][ i%12+1 ];
-
- /* Break days down into seconds and add in remaining time in seconds. */
- timbuf += d;
- timbuf *= 24;
- timbuf += h;
- timbuf *= 60;
- timbuf += n;
- timbuf *= 60;
- timbuf += s;
- /*
- errmsg("dstrtol() : timbuf %ld", timbuf);
- */
- return( timbuf);
-
- }
-
- /*
- * Converts the number `seconds' (the number of seconds since Jan. 1 of
- * startyear) to a date constant of the form given by mask.
- */
- char *ltocon(seconds, mask, dtype)
- unsigned long seconds;
- char *mask;
- int dtype;
- {
- static char datbuf[15];
- unsigned int days;
- int yr, mo=0;
- long time;
- int hr, mn, sd;
-
- # ifdef DDEBUG
- errmsg("ltocon() : seconds %ld mask '%s', type %d", seconds, mask, dtype);
- # endif
-
- if (seconds == 0L)
- return ("");
-
- /* Calculate full number of days in terms of years, months, and days. */
- days = (int) (seconds/86400L);
-
- # ifdef DDEBUG
- errmsg("1> days = %u", days);
- # endif
-
- yr = startyear - 1900;
- mo = 0;
- while (days >= day_tab[ !(yr%4) ][ mo+1 ])
- {
- days -= day_tab[ !(yr%4) ][ mo+1 ];
- mo++;
- yr += mo/12;
- mo %= 12;
- yr %= 100;
- }
-
- # ifdef DDEBUG
- errmsg("2> days = %u", days);
- # endif
-
- yr += ((1900 + yr) < startyear) ? 2000 : 1900;
-
- /*
- * Convert days to the day of the month
- * ie. after 9 days of January it's Jan. 10
- * and changes month to range 1 to 12 from 0 to 11
- */
- /* This messes up compares on dates JH
- days++;
- */
- mo++;
-
- if (dtype == 0) /* Result expected is a Constant */
- {
- mo--;
- yr -= startyear;
- }
-
- /*
- * Convert time less than a full day.
- */
- time = seconds % 86400L;
- hr = (int) (time/3600L);
- time = time%3600L;
- mn = (int) (time/60L);
- sd = (int) (time%60L);
-
- # ifdef DDEBUG
- errmsg("ltocon() : yr %d mo %d days %d hr %d mn %d sd %d", yr, mo, days, hr, mn, sd);
- # endif
-
- /*
- * Create string constant.
- * use mask to create a dtstring from the integer values for year etc
- */
- *datbuf = '\0';
- while (*mask)
- {
- switch (*mask)
- {
- case 'Y' :
- if (*(mask+3) == 'Y')
- {
- intcat(yr/100, datbuf);
- intcat(yr%100, datbuf);
- mask += 3;
- }
- else if (*(mask+2) == 'Y')
- {
- intcat(yr%100, datbuf);
- mask += 2;
- }
- else if (*(mask+1) == 'Y')
- {
- intcat(yr%100, datbuf);
- mask++;
- }
- else
- intcat(yr%100, datbuf);
- break;
-
- case 'M' :
- intcat(mo, datbuf);
- if (*(mask+1) == 'M') mask++;
- break;
-
- case 'D' :
- intcat(days, datbuf);
- if (*(mask+1) == 'D') mask++;
- break;
-
- case 'H' :
- intcat(hr, datbuf);
- if (*(mask+1) == 'H') mask++;
- break;
-
- case 'N' :
- intcat(mn, datbuf);
- if (*(mask+1) == 'N') mask++;
- break;
-
- case 'S' :
- intcat(sd, datbuf);
- if (*(mask+1) == 'S') mask++;
- break;
- }
- mask++;
- }
- strcat(datbuf, "\0");
-
- return(datbuf);
- }
-
- /*
- * today() returns todays date as the number of seconds since
- * Jan 1. 1970
- */
- unsigned long today()
- {
- char tstr[15];
-
- todaystr(tstr);
-
- return (dstrtol(tstr, "YYYYMMDDHHNNSS"));
- }
-
-
- /*
- * Eliminate this routine a.s.a.p
- */
- char *fmt_date(dstr, mask)
- char *dstr, *mask;
- {
- static char datestr[15];
- char *dp = datestr;
-
- todaystr(datestr);
- dp += 2;
- datestr[8] = '\0';
-
- return (dp);
- }
-
-