jac@yoko.rutgers.edu (Jonathan A. Chandross) (05/31/91)
Submitted-by: Andy Werner (st6934@siucvmb.bitnet)
Posting-number: Volume 1, Source:50
Archive-name: util/hyperc/time/time_util
Architecture: ANY_2
Version-number: 1.00
Some more complex time functions, including Gregorian <--> Julian
conversion and date --> day of the week.
Enjoy.
=Read.Me
-time_util
-Version 1.00
-
-More HyperC Time Functions:
-
-The following files were ported to HyperC from the book:
-
-Common C Functions by Kim Jon Brand published by Que Corporation 1985.
-
-zeller.c : Given a date, returns the day of week
-jul.c : Given a date, returns the Julian date (the day of year)
-revjul.c : Given a Julian date and base year, returns the date
-
-scanf.c : By Eric Mcgillicuddy, used in the demo portion of the source.
-setmem.c : Used in revjul.c
-
-To compile, place all of the files in the same directory, and type:
-cc (or ccn) <filename without the .c at the end>
-
-Feedback welcome.
-
- Andy Werner
- st6934@siucvmb.bitnet
-
=Manifest
-
-Read.Me
-jul.c
-revjul.c
-scanf.c
-setmem.c
-zeller.c
-
=jul.c
-
-/* module name : jul.c
- * function name : unsigned int jul()
- * author : Kim J. Brand
- * revision history :
- * |-version-|--date--|-by reason-|
- * 1.0 10/01/84 kb COMMON_C_FUNCTIONS initial release
- * compiled with : HyperC for the Apple II; std.h, scanf.c
- * linked with : s.o, libc
- * linked by : Andy Werner - st6934@siucvmb.bitnet - 3/26/91
- * problems : Julian dates 0-3 reserved for error indicators - NOT!
- * description : returns the julian date from the date string based on a
- * base year given ( the year may be 2 or 4 digits, as the
- * function assumes that 2 = digit years < base year are in
- * the next century).
- */
-
-#include <std.h>
-#include "scanf.c"
-
-/* #include "macros.h" (this was included according to book cited above. */
-
-#define MO 0
-#define DAY 1
-#define YR 2
-
-#define BAD_DIGIT (-1)
-#define BAD_MONTH 367
-#define BAD_DAY 368
-#define BAD_YEAR 369
-
-#define DEMO
-
-UINT jul(date, base) /* Returns unsigned int Julian date from string at
- * date in MM/DD/YY format; Julian base year given by
- * base; day of year returned if base year is the
- * same as date year.
- */
-
-CHAR *date; /* pointer to d-o-w string is returned from this initialized
- * array of pointers to characters
- */
-
-INT base;
-
-{
- LOCAL INT days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
-/* Make a lookup table for the days in each month indexed by the month in the
- * year.
- */
-
- CHAR ch ; /* all purpose character variable */
- INT n = 0 ; /* starting index in input string */
-
- INT mdy[3]; /* array holding the three values created from input string
- * month, day, year.
- */
-
- UINT retjul; /* becomes return value */
-
- /* start at zero in each 'register' */
-
- days[2] = 28; /* static array created at compile time and assumed to be
- * permanent; corrects any changes that may have occurred
- * to February
- */
-
-mdy[MO] = mdy[DAY] = mdy[YR] = 0; /* initialize array values */
-
-while (ch = *date++) /* parse string, through to end */
-{
- if (ch == '-' || ch == '/') /* legal separators are '-', '/' */
- {
- ++n;
- continue;
- }
- if (isdigit(ch)) /* was (!isdigit(ch)) but didn't work */
-
- mdy[n] = 10 * mdy[n] + (ch - '0'); /* adds new digit to total for this */
- /* place, a very simplified atoi() */
- /* that relies on ascii sequences */
-
-/* This print statement was used for debugging */
-
-/*
-printf("\nmdy[MO]=%d, mdy[DAY]=%d, mdy[YR]=%d\r", mdy[MO], mdy[DAY], mdy[YR]);
- */
-
-}
- if (mdy[MO] < 1 || mdy[MO] > 12) /* purge bad months */
- return(BAD_MONTH);
-
-/* If there are only two digits, two-digit years before 1980 are assumed to
- be in the next century; two digit years after the base year are assumed
- to be in this century. The translation becomes (if base == 1980);
- 0-79 = 2000-2079 80-99 = 1980-1999
- */
-
-
- if (mdy[YR] < 100) /* only two digits? */
- {
- if (mdy[YR] < base - 1900) /* prior to base year digits are */
- mdy[YR] += 2000; /* assumed to be in the next century */
- else
-
- mdy[YR] += 1900; /* 01 -> 2001 will make 84 1984 */
- }
- if (mdy[YR] < base) /* return bad years */
- return (BAD_YEAR);
-
- if (mdy[YR] % 4 == 0 && mdy[YR] % 100 != 0 || mdy[YR] % 400 == 0)
-
- days[2] = 29; /* set Februrary days to 29 if leap yr */
-
- if (mdy[DAY] < 1 || mdy[DAY] > days[mdy[MO]])
- return (BAD_DAY); /* return bad days */
-
- retjul = mdy[DAY]; /* set jul equal to days */
- /* in current month */
-
- for (n = 1; n < mdy[MO]; n++)
-
- {
- retjul += days[n];
-/* printf("n=%d, days[n]=%d, retjul=%d \r", n, days[n], retjul); */
- }
-
- for (n = base; n < mdy[YR]; n++)
-
- {
-
- if (n % 4 == 0 && n % 100 != 0 || n % 400 == 0)
-
- retjul += 366;
-
- else
-
- retjul += 365;
-/* printf("days[n]=%d, retjul=%d \r", days[n], retjul);*/
- } /* these printf statements used to debug */
-/* printf("n=%d, days[n]=%d, retjul=%d \r", n, days[n], retjul);*/
- return (retjul);
-}
-
-#ifdef DEMO
-
-main()
-{
- CHAR buff [10]; /* place to build input */
- INT base;
- UINT jul(); /* watch for systems that don't flush non-newline
- * terminated strings. You may need to fflush()
- * after each printf()
- */
- {
- printf("Example: base year = 1984, date = 12/31/84\r");
- printf("\rReturns : 366\r");
- printf("\rAnother example: base year = 1953, date = 5/7/1984\r");
- printf("\rReturns : 11450\r");
- printf("\nEnter base year (19yy): ");
- scanf("%d",&base);
- printf("\nEnter a date (MM/DD/YY or MM/DD/YYYY): ");
- scanf("%s",buff);
- printf("\nThe Julian date is: %u\r\r", jul(buff, base));
- }
- /* print day of week for date entered */
-}
-
-#endif
=revjul.c
-/* module title: revjul.c
- * function name: char *revjul()
- * main() for demo
- *
- * author: Kim J. Brand
- *
- * revision history:
- * version/--date--/by reason--------------------------------------------
- * 1.0 10/01/84 kb COMMON_C_FUNCTIONS initial release
- *
- * compiled with: HyperC - std.h, scanf.c
- * compiled by: Andy Werner - st6934@siucvmb.bitnet - 3/27/91
- * linked with: s.o, libc (int twodates())
- * linked by: Andy Werner - st6934@siucvmb.bitnet
- *
- * problems:
- *
- * description: converts a Julian number into a date string
- *
- */
-
-#include <std.h>
-#include "scanf.c"
-#include "setmem.c"
-
-#define DEMO
-
-CHAR *revjul(jul,year) /* returns pointer to string that */
-INT jul; /* is calendar date for this */
-INT year; /* Julian date in form mm/dd/yy */
-
-{
- /* number of days in each month */
- /* indexed by the month in the year*/
-
- LOCAL INT days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
- LOCAL CHAR date[11];/* a place for returned date string*/
- /* including the null, must be */
- /* static or will evaporate */
-
- INT days_year; /* the days/year for a given year */
- INT n = 1; /* an index into the days/month */
-
- setmem(date, sizeof(date), 0); /* must fill with nulls so */
- /* strlen knows where date ends */
-
- days[2] = 28; /* fix February if changed */
-
- do
- {
- if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
- days_year = 366;
- else
- days_year = 365;
-
- year++, jul -= days_year; /* increment the year and */
- } /* test that does not */
- /* go over top */
- while (jul > 0);
- year--, jul += days_year; /* reverse the effect of going */
- /* too far */
-
- if (days_year == 366) /* if current year is leap */
- days[2] = 29; /* fix February */
-
- do
- jul -= days[n++]; /* subtract days from each */
- while (jul > 0); /* month until jul < 0 */
-
- /* n holds month number */
- --n, jul += days[n]; /* jul has day of month */
-
- year = (year > 1999 ? year : year - 1900);
-
- sprintf(date, "%d/%d/%d", n, jul, year); /* at date build string*/
-
- return (date); /* that returns a pointer */
- /* to the string */
-}
-
-#ifdef DEMO
-
-main() /* a simple demonstration main() */
-
-{
- INT jul;
- INT base;
-
- CHAR *revjul();
-
- {
- printf("\nExample: Julian date = 11450, base year = 1953\r");
- printf("\nReturns: 5/7/84\r");
- printf("\n\rAnother example: Julian date = 366, base year = 1984\r");
- printf("\nReturns: 12/31/84\r\r");
- printf("\nEnter Julian date: ");
- scanf("%d", &jul);
- printf("\nEnter base year: ");
- scanf("%d", &base);
- printf("\nDate = %s\n", revjul(jul, base));
- }
-}
=scanf.c
-/* scanf.c utility function Formatted input for HyperC */
-
-/* #include <std.h> */
-
-#define BUFSIZ 100
-#define TRUE 1
-#define FALSE 0
-
-INT scanf(fmt,args)
-TEXT *fmt;
-INT *args;
-
-{
-TEXT buf[BUFSIZ], temp[BUFSIZ];
-TEXT *str, *ptr;
-INT maxchars, nargs, i, **arv;
-BOOL ignore, space;
-CHAR fctl;
-
-LOCAL INT convert()
-{
-INT val;
-CHAR fctl;
-
-val=0;
-while (isdigit(*fmt))
- val = 10*val + *fmt++ -'0';
-if (!val)
- switch (fctl =*fmt) {
- case 'd':
- case 'D':
- val = 6;
- break;
-
- case 'i':
- case 'I':
- val = 8;
- break;
-
- case 'u':
- case 'U':
- val = 5;
- break;
-
- case 'o':
- case 'O':
- val = 6;
- break;
-
- case 'x':
- case 'X':
- val = 4;
- break;
-
- case 'h':
- case 'H':
- val = 3;
- break;
-
- case 'c':
- case 'C':
- val = 1;
- break;
-
- default:
- val = BUFSIZ - 2;
- break;
- }
- return ((val > BUFSIZ-2) ? BUFSIZ-2 : val);
-}
-
-LOCAL VOID strcopy (dest, src)
-CHAR *src, *dest;
-{
- while (*dest++ = *src++)
- ;
-}
-
-arv=&args;
-nargs=0;
-ignore = FALSE;
-space = FALSE;
-conRead (buf, BUFSIZ);
-str = buf;
-while (*fmt) {
- if (*fmt == ' ')
- space = TRUE;
- if (*fmt++ == '%') {
- if (*fmt == '*') { /* suppression character, useless but k&r use it*/
- ignore = TRUE;
- ++fmt;
- }
- maxchars = convert();
- ptr = temp;
- for (i =0; i < maxchars; i++) {
- if (isspace(*str) && space) {
- str++;
- break;
- }
- *ptr++ = *str++;
- }
- *ptr = '\0';
- ptr = temp;
- if (!ignore)
- switch (fctl = *fmt++) {
- case 'd':
- case 'D':
- case 'i':
- case 'I':
- **arv = atoi (&ptr);
- break;
-
- case 'u':
- case 'U':
- if (*ptr =='-')
- *ptr=' ';
- **arv = atoi (&ptr);
- break;
-
- case 'o':
- case 'O':
- movel (ptr,ptr+1,8);
- ptr[0] = '0';
- **arv = atoi (&ptr);
- break;
-
- case 'x':
- case 'X':
- movel (ptr,&ptr[2],6);
- *ptr = '0'; /* add '0x' prefix to string to make atoi work*/
- ptr[1] = 'x';
- **arv = atoi (&ptr);
- break;
-
- case 'h':
- case 'H':
- **arv = atoi (&ptr);
- break;
-
- case 'c':
- case 'C':
- **arv = *ptr;
- break;
-
- case 'n':
- case 'N':
- arv++;
- break;
-
- case 's':
- case 'S':
- strcopy (*arv, ptr);
- break;
-
- default:
- **arv = '\0';
- break;
- } /*end switch */
- arv++;
- ++nargs;
- fmt--; /* clean up control string pointer */
- } /* end if '%' */
- } /* end while */
-return (nargs);
-} /*end scanf */
-
=setmem.c
-
-/* module title: setmem.c
- * function name: void setmem()
- *
- * author: Kim J. Brand
- * revision history:
- * version/--date--/by reason-------------------------------------------------
- * 1.0 10/01/84 kb COMMON_C_FUNCTIONS initial release
- *
- * compiled with: std.h
- * compiled by: Andy Werner - st6934@siucvmb.bitnet - 3/26/91
- * compiled with: revjul.c
- * linked by: Andy Werner - st6934@siucvmb.bitnet - 3/26/91
- *
- * problems:
- *
- * description: initializes a block of memory pointed to by addr for length
- * given by size with val
- *
- */
-
-VOID setmem(addr, size, val) /* fill, starting at addr, for size, w/ val */
-CHAR *addr;
-UINT size;
-CHAR val;
- {
- while(size--) /* fill up sequential bytes of memory */
- *addr++ = val; /* until size counted down to zero */
- }
=zeller.c
-
-/* module name : zeller.c
- * function name : char * zeller()
- * author : Kim J. Brand
- * revision history :
- * |-version-|--date--|-by reason-|
- * 1.0 10/01/84 kb COMMON_C_FUNCTIONS initial release
- * compiled with : HyperC for the Apple II; std.h, scanf.c
- * linked with : s.o, libc
- * linked by : Andy Werner - st6934@siucvmb.bitnet 4/25/91
- * problems : scanf.c reads the /r and messes up calculation - fixed.
- * description : produces Zeller congruence, given a pointer to the date string
- * passed, in format mm/dd/yy or mm/dd/yyyy and returns a pointer
- * to a string indicating the day of week that the date falls on
- * (separator may also be a hyphen).
- * parameter : pointer to string passed to zeller()
- * returns : day of week
- */
-
-#include <std.h>
-#include "scanf.c"
-
-/* #include "macros.h" (this was included according to book cited above. */
-
-#define Int(x) ((INT) (x)) /* macro defined for zeller to work - needed? */
- /* macro also defined in 'macros.h' above */
-#define MO 0
-#define DAY 1
-#define YR 2
-
-#define BAD_DIGIT (-1)
-
-#define DEMO
-
-CHAR *zeller(date) /* receive pointer to date string;
- * return pointer to day-of-week string
- */
-CHAR *date; /* pointer to d-o-w string is returned from this initialized
- * array of pointers to characters
- */
-
-{
- CHAR ch ; /* all purpose character variable */
- INT n = 0 ; /* starting index in input string */
- INT month; /* temporary variables */
- INT year; /* with obvious uses */
- INT century;
- INT offset; /* offset of year in century */
- INT mdy[3]; /* array holding the three values created from input string
- * month, day, year.
- */
-
-
-LOCAL CHAR *day[] = {"Sunday","Monday","Tuesday","Wednesday",
- "Thursday","Friday","Saturday"};
-
-mdy[MO] = mdy[DAY] = mdy[YR] = 0; /* initialize array values */
-
-while (ch = *date++) /* parse string, through to end */
-{
- if (ch == '-' || ch == '/') /* legal separators are '-', '/' */
- {
- ++n;
- continue;
- }
- if (isdigit(ch)) /* was (!isdigit(ch)) to return error */
-
- mdy[n] = 10 * mdy[n] + (ch - '0');/* adds new digit to total for this */
- /* place, a very simplified atoi() */
- /* that relies on ascii sequences */
-
-/* This print statement was used for debugging */
-
-/*
-printf("\nmdy[MO]=%d, mdy[DAY]=%d, mdy[YR]=%d\r", mdy[MO], mdy[DAY], mdy[YR]);
- */
-
-}
- if (mdy[YR] < 100)
-
- mdy[YR] += 1900; /* accept 2-digit dates for this century*/
-
- if (mdy[MO] > 2)
- {
- month = mdy[MO] - 2; /* adjust year & month based on February*/
- year = mdy[YR];
- }
- else
- {
- month = mdy[MO] + 10;
- year = mdy[YR] - 1;
- }
-
-century = year / 100; /* century as 2-digit number */
-
-offset = year % 100; /* years into century */
-
-/* These print statements were used for debugging */
-
-/* printf("\ncentury=%d, year=%d, offset=%d\r",century, year, offset);
- *
- * printf("\nmonth=%d, mdy[MO]=%d, mdy[DAY]=%d\r",month, mdy[MO], mdy[DAY]);
- */
-
-/* a magic formula for which we must give credit to Zeller */
-
-n = Int((13 * month - 1) / 5) + mdy[DAY] + offset + Int(offset / 4)
- + Int(century / 4) - 2 * century + 77;
-
-n = n - 7 * (n / 7);
-
-return (day[n]);
-}
-
-#ifdef DEMO
-
-main()
-{
- CHAR buff [40]; /* place to build input */
- CHAR *zeller();
- printf("\nThe zeller function calculates the day for a given date.\r");
- printf("\nEnter a date (MM/DD/YY or MM/DD/YYYY): ");
- scanf("%s",buff);
- printf("\nThe day is: %s\r\r",zeller(buff));
- /* print day of week for date entered */
-}
-
-#endif
+ END OF ARCHIVE