[comp.sources.apple2] v001SRC050: time_util -- Time Utility For HyperC

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