home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d9xx / d945 / reminder.lha / Reminder / src / src.lha / CalcDate.c < prev    next >
C/C++ Source or Header  |  1993-04-19  |  6KB  |  235 lines

  1. /* Date calculation routines for Reminder and ReminderCheck */
  2.  
  3. /* $Id: CalcDate.c,v 1.1 1993/04/04 13:37:45 Matti_Rintala Exp $ */
  4.  
  5. #include "Constants.h"
  6. #include "CalcDate.h"
  7.  
  8. #define min(a,b) (((a)<(b)) ? (a) : (b))
  9.  
  10. static monthlen[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  11.  
  12. /* makedate calculates next date that satisfies given conditions */
  13. void makedate(time_t *date, time_t *today,
  14.           short dday, short dmonth, short dyear, short dwday) {
  15.  
  16.   struct tm d;
  17.   int found;
  18.   short year, month, day;
  19.   short year_max, month_max, day_max;
  20.   short year_now, month_now, day_now;
  21.  
  22.   d = *localtime(today);    /* Current date */
  23.   day_now = d.tm_mday;
  24.   month_now = d.tm_mon + 1;
  25.   year_now = d.tm_year + 1900;
  26.  
  27.   found = FALSE;
  28.   year = dyear;
  29.   if (year != 0)
  30.     year_max = year;        /* Year is not wildcard */
  31.   else {
  32.     year = year_now;        /* Otherwise start form now */
  33.     year_max = MAXYEAR;
  34.   }
  35.  
  36.   /* Go through all possible years */
  37.   for (; year <= year_max; year++) {
  38.     /* If we are in the past, try another */
  39.     if (year < year_now)
  40.       continue;
  41.  
  42.     month = dmonth;
  43.     if (month != 0)
  44.       month_max = month;    /* Month is not wildcard */
  45.     else {
  46.       month = (year == year_now) ? month_now : 1; /* Start from now */
  47.       month_max = 12;
  48.     }
  49.  
  50.     /* If we are in the past, try another year */
  51.     if (year == year_now && month_max < month_now)
  52.       continue;
  53.  
  54.     /* Go through all possible months */
  55.     for (; month <= month_max; month++) {
  56.       day = dday;
  57.       day_max = monthlen[month-1] + ((year%4 == 0) ?
  58.                      ((year%400 == 0) ? 0 : 1) : 0);
  59.       if (day != 0) {
  60.     if (dwday == 0)
  61.       day_max = day;    /* No wildcards in day */
  62.     else {
  63.       day = min(day, day_max);
  64.       day_max = min(day+6, day_max); /* Scope is one week */
  65.     }
  66.       }
  67.       else {            /* Day is a wildcard */
  68.     day = (year == year_now && month == month_now) ? day_now : 1;
  69.       }
  70.  
  71.       /* If we are in the past, try another month */
  72.       if (year == year_now && month == month_now && day_max < day_now)
  73.     continue;
  74.  
  75.       /* We should not start earlier than present */
  76.       if (year == year_now && month == month_now && day < day_now)
  77.     day = day_now;
  78.  
  79.       /* We have to find the day */
  80.       for (; day <= day_max; day++) {
  81.     if (dwday == 0 || dwday == weekday(day, month, year)) {
  82.       found =TRUE;
  83.       break;
  84.     }
  85.       }
  86.       if (found) break;
  87.     }
  88.     if (found) break;
  89.   }
  90.  
  91.   /* If found, use the date */
  92.   if (found) {
  93.     /* Now calculate the date */
  94.     d.tm_sec = d.tm_min = d.tm_hour = 0;
  95.     d.tm_mday = day;
  96.     d.tm_mon = month - 1;
  97.     d.tm_year = year - 1900;
  98.     
  99.     *date = mktime(&d);        /* Make the date */
  100.   }
  101.   else {
  102.     /* Else try previous one */
  103.     makeprevdate(date, today, dday, dmonth, dyear, dwday);
  104.   }
  105. }
  106.  
  107. /* makeprevdate calculates previous date that satisfies given conditions */
  108. void makeprevdate(time_t *date, time_t *today,
  109.           short dday, short dmonth, short dyear, short dwday) {
  110.  
  111.   struct tm d;
  112.   int found;
  113.   short year, month, day;
  114.   short year_min, month_min, day_min;
  115.   short year_now, month_now, day_now;
  116.  
  117.   d = *localtime(today);    /* Current date */
  118.   day_now = d.tm_mday;
  119.   month_now = d.tm_mon + 1;
  120.   year_now = d.tm_year + 1900;
  121.  
  122.   found = FALSE;
  123.   year = dyear;
  124.   if (year != 0)
  125.     year_min = year;        /* Year is not wildcard */
  126.   else {
  127.     year = year_now;        /* Otherwise start form now */
  128.     year_min = MINYEAR;
  129.   }
  130.  
  131.   /* Go through all possible years */
  132.   for (; year >= year_min; year--) {
  133.     /* If we are in the future, try next */
  134.     if (year > year_now)
  135.       continue;
  136.  
  137.     month = dmonth;
  138.     if (month != 0)
  139.       month_min = month;    /* Month is not wildcard */
  140.     else {
  141.       month = (year == year_now) ? month_now : 12; /* Start from now */
  142.       month_min = 1;
  143.     }
  144.  
  145.     /* If we are in the future, try another year */
  146.     if (year == year_now && month_min > month_now)
  147.       continue;
  148.  
  149.     /* Go through all possible months */
  150.     for (; month >= month_min; month--) {
  151.       day_min = dday;
  152.       day = monthlen[month-1] + ((year%4 == 0) ?
  153.                  ((year%400 == 0) ? 0 : 1) : 0);
  154.       if (day_min != 0) {
  155.     if (dwday == 0)
  156.       day = day_min;    /* No wildcards in day */
  157.     else {
  158.       day = min(day_min+6, day); /* Scope is one week */
  159.     }
  160.       }
  161.       else {            /* Day is a wildcard */
  162.     day = (year == year_now && month == month_now) ? day_now : day;
  163.     day_min = 1;
  164.       }
  165.  
  166.       /* If we are in the future, try another month */
  167.       if (year == year_now && month == month_now && day_min > day_now)
  168.     continue;
  169.  
  170.       /* We should not start later than present */
  171.       if (year == year_now && month == month_now && day > day_now)
  172.     day = day_now;
  173.  
  174.       /* We have to find the day */
  175.       for (; day >= day_min; day--) {
  176.     if (dwday == 0 || dwday == weekday(day, month, year)) {
  177.       found =TRUE;
  178.       break;
  179.     }
  180.       }
  181.       if (found) break;
  182.     }
  183.     if (found) break;
  184.   }
  185.  
  186.   d.tm_sec = d.tm_min = d.tm_hour = 0;
  187.  
  188.   /* If date found */
  189.   if (found) {
  190.     /* Now calculate the date */
  191.     d.tm_mday = day;
  192.     d.tm_mon = month - 1;
  193.     d.tm_year = year - 1900;
  194.   }
  195.   else {
  196.     /* Else use 1.1.1990 */
  197.     d.tm_mday = 1;
  198.     d.tm_mon = 0;
  199.     d.tm_year = 90;
  200.   }
  201.  
  202.   *date = mktime(&d);        /* Make the date */
  203. }
  204.  
  205. /* weekday gives the day of the week */
  206. short weekday(short day, short month, short year) {
  207.  
  208.   struct tm date;
  209.   time_t time;
  210.  
  211.   date.tm_sec = date.tm_min = date.tm_hour = 0;
  212.   date.tm_mday = day;
  213.   date.tm_mon = month - 1;
  214.   date.tm_year = year - 1900;
  215.   time = mktime(&date);        /* Make a time_t */
  216.   date = *localtime(&time);    /* Calculate back to struct */
  217.  
  218.   /* Day of the week is now in date */
  219.   return (short)((date.tm_wday == 0) ? 7 : date.tm_wday);
  220. }
  221.  
  222. /* gettoday gets today's date (without time of day) */
  223. void gettoday(time_t *today) {
  224.  
  225.   struct tm *tmptr;
  226.  
  227.   time(today);            /* Get date */
  228.   
  229.   tmptr = localtime(today);    /* Change to struct */
  230.   /* Now zero all time of day fields */
  231.   tmptr->tm_sec = tmptr->tm_min = tmptr->tm_hour = 0;
  232.   *today = mktime(tmptr);    /* Convert back to time_t */
  233. }
  234.  
  235.