home *** CD-ROM | disk | FTP | other *** search
- #include "defines.h"
- #include "globals.h"
- #include "protos.h"
-
- /***************************************************************/
- /* */
- /* int TryNextDate(int *retday, int *retmon, int *retyr, */
- /* int startday, int startmon, int startyr, */
- /* int conday, int conmon, int conyr, */
- /* int wkday, int cons, int inc) */
- /* */
- /* This function tries to find the next date satisfying */
- /* the given constraints. Returns */
- /* 0 for success. Returns non-zero if a constraint would */
- /* be violated. Note that if DAY and WEEKDAY are both */
- /* constrained, then MONTH and YEAR may be violated. */
- /* Otherwise, all constraints are honoured. */
- /* The starting point for the search is thisday, etc. */
- /* */
- /* If inc is non-zero, then the search begins from the day */
- /* after the specified date. Note that this function assumes */
- /* that the given date is valid. */
- /* */
- /***************************************************************/
- #ifdef __STDC__
- int TryNextDate(int *retday, int *retmon, int *retyr,
- int d, int m, int y,
- int conday, int conmon, int conyr,
- int wkday, int cons, int inc)
- #else
- int TryNextDate(retday, retmon, retyr, d, m, y, conday, conmon, conyr,
- wkday, cons, inc)
- int *retday, *retmon, *retyr, d, m, y, conday, conmon, conyr, wkday, cons, inc;
-
- #endif
-
- {
- int jul, jul2;
- int dd = d, mm = m, yy = y;
-
- if (inc)
- {
- d++;
- if (d > DaysInMonth(m, y)) {
- m++; d = 1;
- if (m > 11) {
- y++; m = 0;
- }
- }
- }
-
-
- switch (cons & 15) {
-
- case 0: /* No constraints - just use the start date */
- *retday = d;
- *retmon = m;
- *retyr = y;
- return 0;
-
- case 1: /* Day constrained to be d */
- *retday = conday;
- if (d > conday) {
- m++;
- if (m > 11) {y++; m=0;}
- }
- while (conday > DaysInMonth(m, y)) {
- m++;
- if (m > 11) {y++; m=0;}
- }
- *retmon = m;
- *retyr = y;
- return 0;
-
- case 2: /* Month constrained to be m */
- *retmon = conmon;
- if (m > conmon) {y++; d = 1;}
- else if (m < conmon) d = 1;
- *retday = d;
- *retyr = y;
- return 0;
-
- case 3: /* Month and day constrained */
- *retmon = conmon;
- *retday = conday;
- if (m > conmon || (m == conmon && d > conday)) y++;
- while (conday > DaysInMonth(conmon, y)) y++;
- *retyr = y;
- return 0;
-
- case 4: /* Year alone constrained */
- if (y > conyr) return 1;
- *retyr = conyr;
- if (y < conyr) {
- *retmon = 0;
- *retday = 1;
- }
- else {
- *retmon = m;
- *retday = d;
- }
- return 0;
-
- case 5: /* Year and day constrained */
- if (y > conyr) return 1;
- *retyr = conyr;
- *retday = conday;
- if (y < conyr) {
- *retmon = 0;
- return 0;
- }
- if (d > conday) {
- m++;
- if (m > 11) return 1;
- }
- while (conday > DaysInMonth(m, y)) {
- m++;
- if (m > 11) return 1;
- }
- *retmon = m;
- return 0;
-
- case 6: /* Year and month constrained */
- if (y > conyr || (y == conyr && m > conmon)) return 1;
- *retyr = conyr;
- *retmon = conmon;
- if (y < conyr || (y == conyr && m < conmon)) {
- *retday = 1;
- return 0;
- }
- *retday = d;
- return 0;
-
- case 7: /* Year, month and day constrained */
- *retday = conday;
- *retmon = conmon;
- *retyr = conyr;
- if (y > conyr || (y == conyr && m > conmon) ||
- (y == conyr && m == conmon && d > conday)) return 1;
- return 0;
-
- case 8: /* Only the weekday constrained. Let's go to Julian mode */
- jul = Julian(d, m, y);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- FromJulian(jul, retday, retmon, retyr);
- return 0;
-
- case 9: /* GASP! day and weekday constrained .. bleah! */
- /* First, try last month. */
- jul2 = Julian(d, m, y);
- if (m != 0 || y != BASE)
- {
- mm--;
- if (mm < 0) {yy--; mm = 11;}
-
- /* If there are fewer days in month than required, it
- can't possibly match. */
- if (conday <= DaysInMonth(mm, yy)) {
- jul = Julian(conday, mm, yy);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- if (jul >= jul2) { /* SUCCESS! */
- FromJulian(jul, retday, retmon, retyr);
- return 0;
- }
- }
- }
- /* Didn't work - try this month */
- if (conday <= DaysInMonth(m, y)) {
- jul = Julian(conday, m, y);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- if (jul >= jul2) { /* SUCCESS! */
- FromJulian(jul, retday, retmon, retyr);
- return 0;
- }
- }
- /* Argh! Try next available month */
- mm = m;
- yy = y;
- do {
- mm++;
- if (mm > 11) {mm = 0; yy++;}
- } while (conday > DaysInMonth(mm, yy));
- jul = Julian(conday, mm, yy);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- FromJulian(jul, retday, retmon, retyr);
- return 0;
-
- case 10: /* Month and Weekday constrained */
- if (m < conmon) {
- jul = Julian(1, conmon, y);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- FromJulian(jul, retday, retmon, retyr);
- return 0;
- } else if (m == conmon) {
- jul = Julian(d, conmon, y);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- FromJulian(jul, retday, retmon, retyr);
- if (*retmon != conmon) {
- jul = Julian(1, conmon, y+1);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- FromJulian(jul, retday, retmon, retyr);
- }
- return 0;
- } else { /* m > conmon */
- jul = Julian(1, conmon, y+1);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- FromJulian(jul, retday, retmon, retyr);
- return 0;
- }
-
- case 11: /* Day, Month and Weekday constrained */
- jul2 = Julian(d, m, y);
-
- /* Blip up to next valid year */
- while (conday > DaysInMonth(conmon, y)) y++;
-
- /* Try this year */
- jul = Julian(conday, conmon, y);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- if (jul >= jul2) {
- FromJulian(jul, retday, retmon, retyr);
- return 0;
- }
-
- /* Must be next year */
- jul = Julian(conday, conmon, y+1);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- FromJulian(jul, retday, retmon, retyr);
- return 0;
-
- case 12: /* Weekday and year specified */
- if (y > conyr) return 1;
- if (y == conyr) {mm = m; dd = d;} else {mm = 0; dd = 1;}
- jul = Julian(dd, mm, conyr);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- FromJulian(jul, retday, retmon, retyr);
- if (*retyr == conyr) return 0; else return 1;
-
- case 13: /* Weekday, year and day specified */
- if (y > conyr+1 || (y > conyr && m>0)) return 1;
- jul2 = Julian(d, m, y);
- if (y > conyr ) {
- jul = Julian(conday, 11, conyr);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- if (jul >= jul2) {
- FromJulian(jul, retday, retmon, retyr);
- return 0;
- }
- } else if (y < conyr) {
- jul = Julian(conday, 0, conyr);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- FromJulian(jul, retday, retmon, retyr);
- return 0;
- }
- else {
- /* Try last month */
- if (m > 0) {
- mm = m - 1;
- while (conday > DaysInMonth(mm, y)) mm--;
- jul = Julian(conday, mm, y);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- if (jul >= jul2) {
- FromJulian(jul, retday, retmon, retyr);
- return 0;
- }
- }
- /* Try this month */
- if (conday <= DaysInMonth(m,y)) {
- jul = Julian(conday, m, y);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- if (jul >= jul2) {
- FromJulian(jul, retday, retmon, retyr);
- return 0;
- }
- }
- /* Try next month */
- if (m == 11) return 1;
- m++;
- while (conday > DaysInMonth(m, y)) m++;
- jul = Julian(conday, m, y);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- FromJulian(jul, retday, retmon, retyr);
- return 0;
- }
-
- case 14: /* Weekday, Month and Year specified */
- if (y > conyr || (y == conyr && m > conmon)) return 1;
- if (conyr > y || (conyr == y && conmon > m)) {
- jul = Julian(1, conmon, conyr);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- FromJulian(jul, retday, retmon, retyr);
- if (*retmon == conmon) return 0; else return 1;
- } else {
- jul = Julian(d, m, y);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- FromJulian(jul, retday, retmon, retyr);
- if (*retmon == conmon) return 0; else return 1;
-
- }
-
- case 15: /* Weekday, day, month and year specified */
- jul2 = Julian(d, m, y);
- jul = Julian(conday, conmon, conyr);
- while (!(wkday & (1 << (jul % 7)))) jul++;
- FromJulian(jul, retday, retmon, retyr);
- if (jul < jul2) return 1;
- return 0;
- }
- }
-