home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Jason Aller Floppy Collection
/
125.img
/
PRO-C4.ZIP
/
BENCH1.ZIP
/
BENCH
/
DATE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-28
|
11KB
|
554 lines
/* ==( 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);
}