home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / remind23.lzh / remind.1 / nextdate.c next >
C/C++ Source or Header  |  1991-02-24  |  9KB  |  310 lines

  1. #include "defines.h"
  2. #include "globals.h"
  3. #include "protos.h"
  4.  
  5. /***************************************************************/
  6. /*                                                             */
  7. /*  int TryNextDate(int *retday, int *retmon, int *retyr,      */
  8. /*                  int startday, int startmon, int startyr,   */
  9. /*                  int conday, int conmon, int conyr,         */
  10. /*                  int wkday, int cons, int inc)              */
  11. /*                                                             */
  12. /*  This function tries to find the next date satisfying       */
  13. /*  the given constraints.  Returns                            */
  14. /*  0 for success.  Returns non-zero if a constraint would     */
  15. /*  be violated.  Note that if DAY and WEEKDAY are both        */
  16. /*  constrained, then MONTH and YEAR may be violated.          */
  17. /*  Otherwise, all constraints are honoured.                   */
  18. /*  The starting point for the search is thisday, etc.         */
  19. /*                                                             */
  20. /*  If inc is non-zero, then the search begins from the day    */
  21. /*  after the specified date.  Note that this function assumes */
  22. /*  that the given date is valid.                              */
  23. /*                                                             */
  24. /***************************************************************/
  25. #ifdef __STDC__
  26. int TryNextDate(int *retday, int *retmon, int *retyr,
  27.         int d, int m, int y,
  28.         int conday, int conmon, int conyr,
  29.         int wkday, int cons, int inc)
  30. #else
  31. int TryNextDate(retday, retmon, retyr, d, m, y, conday, conmon, conyr,
  32.                 wkday, cons, inc)
  33.      int *retday, *retmon, *retyr, d, m, y, conday, conmon, conyr, wkday, cons, inc;
  34.      
  35. #endif
  36.  
  37. {
  38.    int jul, jul2;
  39.    int dd = d, mm = m, yy = y;
  40.  
  41.    if (inc)
  42.    {
  43.       d++;
  44.       if (d > DaysInMonth(m, y)) {
  45.      m++; d = 1;
  46.      if (m > 11) {
  47.         y++; m = 0;
  48.      }
  49.       }
  50.    }
  51.  
  52.  
  53.    switch (cons & 15) {
  54.  
  55.       case 0:  /* No constraints - just use the start date */
  56.      *retday = d;
  57.      *retmon = m;
  58.      *retyr  = y;
  59.      return 0;
  60.  
  61.       case 1: /* Day constrained to be d */
  62.      *retday = conday;
  63.      if (d > conday) {
  64.         m++;
  65.         if (m > 11) {y++; m=0;}
  66.      }
  67.      while (conday > DaysInMonth(m, y)) {
  68.         m++;
  69.         if (m > 11) {y++; m=0;}
  70.      }
  71.      *retmon = m;
  72.      *retyr = y;
  73.      return 0;
  74.  
  75.       case 2: /* Month constrained to be m */
  76.      *retmon = conmon;
  77.      if (m > conmon) {y++; d = 1;}
  78.      else if (m < conmon) d = 1;
  79.      *retday = d;
  80.      *retyr = y;
  81.      return 0;
  82.  
  83.       case 3: /* Month and day constrained */
  84.      *retmon = conmon;
  85.      *retday = conday;
  86.      if (m > conmon || (m == conmon && d > conday)) y++;
  87.      while (conday > DaysInMonth(conmon, y)) y++;
  88.      *retyr = y;
  89.      return 0;
  90.  
  91.       case 4: /* Year alone constrained */
  92.      if (y > conyr) return 1;
  93.      *retyr = conyr;
  94.      if (y < conyr) {
  95.         *retmon = 0;
  96.         *retday = 1;
  97.      }
  98.      else {
  99.         *retmon = m;
  100.         *retday = d;
  101.      }
  102.      return 0;
  103.  
  104.       case 5: /* Year and day constrained */
  105.      if (y > conyr) return 1;
  106.      *retyr = conyr;
  107.      *retday = conday;
  108.      if (y < conyr) {
  109.         *retmon = 0;
  110.         return 0;
  111.      }
  112.      if (d > conday) {
  113.        m++;
  114.        if (m > 11) return 1;
  115.      }
  116.      while (conday > DaysInMonth(m, y)) {
  117.         m++;
  118.         if (m > 11) return 1;
  119.      }
  120.      *retmon = m;
  121.      return 0;
  122.  
  123.       case 6: /* Year and month constrained */
  124.      if (y > conyr || (y == conyr && m > conmon)) return 1;
  125.      *retyr = conyr;
  126.      *retmon = conmon;
  127.      if (y < conyr || (y == conyr && m < conmon)) {
  128.         *retday = 1;
  129.         return 0;
  130.      }
  131.      *retday = d;
  132.      return 0;
  133.  
  134.       case 7: /* Year, month and day constrained */
  135.      *retday = conday;
  136.      *retmon = conmon;
  137.      *retyr = conyr;
  138.      if (y > conyr || (y == conyr && m > conmon) ||
  139.          (y == conyr && m == conmon && d > conday)) return 1;
  140.      return 0;
  141.  
  142.       case 8: /* Only the weekday constrained.  Let's go to Julian mode */
  143.      jul = Julian(d, m, y);
  144.      while (!(wkday & (1 << (jul % 7)))) jul++;
  145.      FromJulian(jul, retday, retmon, retyr);
  146.      return 0;
  147.  
  148.       case 9: /* GASP! day and weekday constrained .. bleah! */
  149.      /* First, try last month. */
  150.      jul2 = Julian(d, m, y);
  151.      if (m != 0 || y != BASE)
  152.      {
  153.         mm--;
  154.         if (mm < 0) {yy--; mm = 11;}
  155.  
  156.         /* If there are fewer days in month than required, it
  157.            can't possibly match.  */
  158.         if (conday <= DaysInMonth(mm, yy)) {
  159.            jul = Julian(conday, mm, yy);
  160.            while (!(wkday & (1 << (jul % 7)))) jul++;
  161.            if (jul >= jul2) { /* SUCCESS! */
  162.           FromJulian(jul, retday, retmon, retyr);
  163.           return 0;
  164.            }
  165.         }
  166.      }
  167.      /* Didn't work - try this month */
  168.      if (conday <= DaysInMonth(m, y)) {
  169.         jul = Julian(conday, m, y);
  170.         while (!(wkday & (1 << (jul % 7)))) jul++;
  171.         if (jul >= jul2) { /* SUCCESS! */
  172.            FromJulian(jul, retday, retmon, retyr);
  173.            return 0;
  174.         }
  175.      }
  176.      /* Argh!  Try next available month */
  177.      mm = m;
  178.      yy = y;
  179.      do {
  180.         mm++;
  181.         if (mm > 11) {mm = 0; yy++;}
  182.      } while (conday > DaysInMonth(mm, yy));
  183.      jul = Julian(conday, mm, yy);
  184.      while (!(wkday & (1 << (jul % 7)))) jul++;
  185.      FromJulian(jul, retday, retmon, retyr);
  186.      return 0;
  187.  
  188.       case 10: /* Month and Weekday constrained */
  189.      if (m < conmon) {
  190.         jul = Julian(1, conmon, y);
  191.         while (!(wkday & (1 << (jul % 7)))) jul++;
  192.         FromJulian(jul, retday, retmon, retyr);
  193.         return 0;
  194.      } else if (m == conmon) {
  195.         jul = Julian(d, conmon, y);
  196.         while (!(wkday & (1 << (jul % 7)))) jul++;
  197.         FromJulian(jul, retday, retmon, retyr);
  198.         if (*retmon != conmon) {
  199.            jul = Julian(1, conmon, y+1);
  200.            while (!(wkday & (1 << (jul % 7)))) jul++;
  201.            FromJulian(jul, retday, retmon, retyr);
  202.         }
  203.         return 0;
  204.      } else { /* m > conmon */
  205.         jul = Julian(1, conmon, y+1);
  206.         while (!(wkday & (1 << (jul % 7)))) jul++;
  207.         FromJulian(jul, retday, retmon, retyr);
  208.         return 0;
  209.      }
  210.  
  211.       case 11: /* Day, Month and Weekday constrained */
  212.      jul2 = Julian(d, m, y);
  213.  
  214.      /* Blip up to next valid year */
  215.      while (conday > DaysInMonth(conmon, y)) y++;
  216.  
  217.      /* Try this year */
  218.      jul = Julian(conday, conmon, y);
  219.      while (!(wkday & (1 << (jul % 7)))) jul++;
  220.      if (jul >= jul2) {
  221.         FromJulian(jul, retday, retmon, retyr);
  222.         return 0;
  223.      }
  224.  
  225.      /* Must be next year */
  226.      jul = Julian(conday, conmon, y+1);
  227.      while (!(wkday & (1 << (jul % 7)))) jul++;
  228.      FromJulian(jul, retday, retmon, retyr);
  229.      return 0;
  230.  
  231.       case 12: /* Weekday and year specified */
  232.      if (y > conyr) return 1;
  233.      if (y == conyr) {mm = m; dd = d;} else {mm = 0; dd = 1;}
  234.      jul = Julian(dd, mm, conyr);
  235.      while (!(wkday & (1 << (jul % 7)))) jul++;
  236.      FromJulian(jul, retday, retmon, retyr);
  237.      if (*retyr == conyr) return 0; else return 1;
  238.  
  239.       case 13: /* Weekday, year and day specified */
  240.      if (y > conyr+1 || (y > conyr && m>0)) return 1;
  241.      jul2 = Julian(d, m, y);
  242.      if (y > conyr ) {
  243.         jul = Julian(conday, 11, conyr);
  244.         while (!(wkday & (1 << (jul % 7)))) jul++;
  245.         if (jul >= jul2) {
  246.            FromJulian(jul, retday, retmon, retyr);
  247.            return 0;
  248.         }
  249.      } else if (y < conyr) {
  250.         jul = Julian(conday, 0, conyr);
  251.         while (!(wkday & (1 << (jul % 7)))) jul++;
  252.         FromJulian(jul, retday, retmon, retyr);
  253.         return 0;
  254.      }
  255.      else {
  256.         /* Try last month */
  257.         if (m > 0) {
  258.            mm = m - 1;
  259.            while (conday > DaysInMonth(mm, y)) mm--;
  260.            jul = Julian(conday, mm, y);
  261.            while (!(wkday & (1 << (jul % 7)))) jul++;
  262.            if (jul >= jul2) {
  263.           FromJulian(jul, retday, retmon, retyr);
  264.           return 0;
  265.            }
  266.         }
  267.         /* Try this month */
  268.         if (conday <= DaysInMonth(m,y)) {
  269.            jul = Julian(conday, m, y);
  270.            while (!(wkday & (1 << (jul % 7)))) jul++;
  271.            if (jul >= jul2) {
  272.           FromJulian(jul, retday, retmon, retyr);
  273.           return 0;
  274.            }
  275.         }
  276.         /* Try next month */
  277.         if (m == 11) return 1;
  278.         m++;
  279.         while (conday > DaysInMonth(m, y)) m++;
  280.         jul = Julian(conday, m, y);
  281.         while (!(wkday & (1 << (jul % 7)))) jul++;
  282.         FromJulian(jul, retday, retmon, retyr);
  283.         return 0;
  284.      }
  285.  
  286.       case 14:  /* Weekday, Month and Year specified */
  287.      if (y > conyr || (y == conyr && m > conmon)) return 1;
  288.      if (conyr > y || (conyr == y && conmon > m)) {
  289.         jul = Julian(1, conmon, conyr);
  290.         while (!(wkday & (1 << (jul % 7)))) jul++;
  291.         FromJulian(jul, retday, retmon, retyr);
  292.         if (*retmon == conmon) return 0; else return 1;
  293.      } else {
  294.         jul = Julian(d, m, y);
  295.         while (!(wkday & (1 << (jul % 7)))) jul++;
  296.         FromJulian(jul, retday, retmon, retyr);
  297.         if (*retmon == conmon) return 0; else return 1;
  298.  
  299.      }
  300.  
  301.       case 15: /* Weekday, day, month and year specified */
  302.      jul2 = Julian(d, m, y);
  303.      jul = Julian(conday, conmon, conyr);
  304.      while (!(wkday & (1 << (jul % 7)))) jul++;
  305.      FromJulian(jul, retday, retmon, retyr);
  306.      if (jul < jul2) return 1;
  307.      return 0;
  308.    }
  309. }
  310.