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