home *** CD-ROM | disk | FTP | other *** search
- From: jac@yoko.rutgers.edu (Jonathan A. Chandross)
- Newsgroups: comp.sources.apple2
- Subject: v001SRC050: time_util -- Time Utility For HyperC
- Message-ID: <May.31.11.35.13.1991.7175@yoko.rutgers.edu>
- Date: 31 May 91 15:35:14 GMT
- Approved: jac@paul.rutgers.edu
-
-
- 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
-