home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2059 / util.c next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  4.5 KB  |  235 lines

  1. /*
  2.  *    util.c : Some miscellaneous routines for handling dates.
  3.  *
  4.  *    George Ferguson (ferguson@cs.rochester.edu), 27 Oct 1990.
  5.  *
  6.  *      $Id: util.c,v 1.1 90/10/28 13:05:14 ferguson Exp $
  7.  *
  8.  */
  9.  
  10. #include <sys/time.h>
  11. #include <ctype.h>
  12. extern char *shortMonStr[];
  13.  
  14. /*
  15.  * Functions defined here:
  16.  */
  17. int computeDOW(), firstDOW(), lastDay();
  18. void getCurrentDate();
  19. int parseDate();
  20.  
  21. /*
  22.  * Global data
  23.  */
  24. static int mon_max[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
  25.  
  26. /*    -    -    -    -    -    -    -    -    */
  27. /*
  28.  *    computeDOW(day,mon,year) : Returns the day of the week for the
  29.  *        requested date (0=Sunday, 1=Monday, etc).
  30.  *        This newer, faster, method is courtesy findeis@alberta.
  31.  */
  32. int
  33. computeDOW(d,m,y)
  34. int d,m,y;
  35. {
  36.     static int dp [12] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
  37.     register int y4, s;
  38.  
  39.     y = y - 1;        /* actually y - 1901 */
  40.     s = (y/4) * 5;
  41.     y4 = y % 4;
  42.     if ((y4 == 3) && (m>1)) s++;
  43.     s = s + y4 + dp[m] + d + 1;
  44.     return (s % 7);
  45. }
  46.  
  47. /*
  48.  *    firstDOW(mon,year) : Returns the doy of the week for the first
  49.  *        day of the given month and year.
  50.  */
  51. int
  52. firstDOW(mon,year)
  53. int mon,year;
  54. {
  55.     return(computeDOW(1,mon,year));
  56. }
  57.  
  58. /*
  59.  *    lastDay(mon,year) : Returns the last day of the requested
  60.  *        month (and handles leap years, etc).
  61.  */
  62. int
  63. lastDay(mon,year)
  64. int mon,year;
  65. {
  66.     if ((mon == 1)&&(dysize(year+1900) == 366))
  67.         return(29);
  68.     else return(mon_max[mon]);
  69. }
  70.  
  71. /*
  72.  *    nextDay(d,m,y) : Increment d,m,y to the next day
  73.  */
  74. void
  75. nextDay(dp,mp,yp)
  76. int *dp,*mp,*yp;
  77. {
  78.     if (*dp != lastDay(*mp,*yp))
  79.     *dp += 1;
  80.     else {
  81.     *dp = 1;
  82.     if (*mp != 11)
  83.         *mp += 1;
  84.     else {
  85.         *mp = 0;
  86.         *yp += 1;
  87.     }
  88.     }
  89. }
  90.  
  91. /*
  92.  *    prevDay(d,m,y) : Decrement d,m,y to the previous day
  93.  */
  94. void
  95. prevDay(dp,mp,yp)
  96. int *dp,*mp,*yp;
  97. {
  98.     if (*dp != 1)
  99.     *dp -= 1;
  100.     else {
  101.     if (*mp != 0)
  102.         *mp -= 1;
  103.     else {
  104.         *yp -= 1;
  105.         *mp = 0;
  106.     }
  107.     *dp = lastDay(*mp,*yp);
  108.     }
  109. }
  110.  
  111. /*    -    -    -    -    -    -    -    -    */
  112. /*
  113.  * getCurrentDate() : What else?
  114.  */
  115. void
  116. getCurrentDate(dp,mp,yp)
  117. int *dp,*mp,*yp;
  118. {
  119.   struct timeval t;
  120.   struct timezone tz;
  121.   struct tm *r;
  122.  
  123.   gettimeofday(&t,&tz);
  124.   r = localtime(&(t.tv_sec));
  125.   *dp = r->tm_mday;
  126.   *mp = r->tm_mon;
  127.   *yp = r->tm_year;
  128. }
  129.  
  130. /*    -    -    -    -    -    -    -    -    */
  131. /*
  132.  *    parseDate(text,dp,mp,yp) : Parse the string text into a date which is
  133.  *        either an absolute or a relative date as follows:
  134.  *
  135.  *    rel date = [+-]{<num>[dmy]}*
  136.  *    abs date = [<day><mon><year>]* where <day> = <num> less than 32
  137.  *                         <mon> = <string>
  138.  *                         <year>= <num> greater than 32
  139.  *    The variables pointed to by dp,mp,yp are filled in with the new date.
  140.  *    Whitespace is skipped.
  141.  *    Returns -1 if the date was garbled, else 0.
  142.  */
  143. int
  144. parseDate(text,dp,mp,yp)
  145. char *text;
  146. int *dp,*mp,*yp;
  147. {
  148.     int day,mon,year,last,num,sign,i;
  149.  
  150.     day = mon = year = 0;
  151.     last = lastDay(*mp,*yp);
  152.     if (*text == '+' || *text == '-') {    /* relative date */
  153.     sign = *text++;            /* save sign */
  154.     while (*text) {            /* parse string... */
  155.         while (isspace(*text))            /* skip white space */
  156.         text += 1;
  157.         num = 0;
  158.         while (*text >= '0' && *text <= '9') {    /* get a number */
  159.         num = num * 10 + *text - '0';
  160.         text += 1;
  161.         }
  162.         switch(*text) {                /* and a specifier */
  163.         case '\0':        /* no specifier => days */
  164.         case 'D' :
  165.         case 'd' : day = num;
  166.                break;
  167.         case 'M' :
  168.         case 'm' : mon = num;
  169.                break;
  170.         case 'Y' :
  171.         case 'y' : year = num;
  172.                break;
  173.         default: return(-1);
  174.         }
  175.         if (*text != '\0')            /* continue unless at end */
  176.         text += 1;
  177.     }
  178.     if (sign == '+') {        /* now set the `current' date */
  179.         *dp += day;
  180.         if (*dp > last) {
  181.         *dp -= last;
  182.         *mp += 1;
  183.         }
  184.         *mp += mon;
  185.         if (*mp > 11) {
  186.         *mp -= 12;
  187.         *yp += 1;
  188.         }
  189.         *yp += year;
  190.     } else {
  191.         *yp -= year;
  192.         *mp -= mon;
  193.         if (*mp < 0) {
  194.         *mp += 12;
  195.         *yp -= 1;
  196.         }
  197.         *dp -= day;
  198.         if (*dp < 1) {
  199.         *mp -= 1;
  200.         if (*mp < 0) {
  201.             *mp = 11;
  202.             *yp -= 1;
  203.         }
  204.         *dp += last;
  205.         }
  206.     }
  207.     } else {                /* absolute date */
  208.     while (*text) {
  209.         while (isspace(*text))        /* skip white space */
  210.         text += 1;
  211.         num = 0;
  212.         while (*text >= '0' && *text <= '9') {    /* try a number */
  213.         num = num * 10 + *text - '0';
  214.         text += 1;
  215.         }
  216.         if (num == 0) {        /* no number try a month */
  217.         if (islower(*text))
  218.             *text = toupper(*text);
  219.         for (i=0; i < 12 && strcmp(text,shortMonStr[i]) != 0; i++) ;
  220.         if (i == 12) {
  221.             return(-1);
  222.         } else {
  223.             *mp = i;
  224.             text += 3;
  225.         }
  226.         } else if (num < 32)    /* number was either day or year */
  227.         *dp = num;
  228.         else if (num >= 1900)
  229.         *yp = num - 1900;
  230.         else *yp = num;
  231.     }
  232.     }
  233.     return(0);
  234. }
  235.