home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Scheduling / Cassandra / Source / calendar.m < prev    next >
Encoding:
Text File  |  1991-12-20  |  11.1 KB  |  566 lines

  1. //
  2. // calendar.m
  3. // Copyright (c) 1989, 1990 by Jiro Nakamura 
  4. // All rights reserved
  5. //
  6. // Calendar routine package.
  7. //
  8. // RCS Information
  9. // Revision Number->    $Revision: 2.7 $
  10. // Last Revised->    $Date: 91/12/20 14:04:59 $
  11. //
  12. static char rcsid[] = "$Header: /shaman330/Users/jiro/Programming/Cassandra/src/RCS/calendar.m,v 2.7 91/12/20 14:04:59 jiro Exp Locker: jiro $";
  13.  
  14. #import <stdio.h>
  15. #import <c.h>
  16. #import <ctype.h>
  17. #import <appkit/Panel.h>       /* for NXRunAlertPanel */
  18. #import "calendar.h"
  19. #import "misc.h"
  20.  
  21. const int ayear[13] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273,
  22.              304, 334, 365};
  23. const char *months[12]= {"January", "February", "March", "April", "May", 
  24.             "June", "July","August","September",
  25.             "October","November","December"};
  26. const char *shortMonths[12] ={"Jan", "Feb", "Mar", "Apr",  "May",
  27.                 "Jun", "Jul", "Aug", "Sep", 
  28.                   "Oct", "Nov", "Dec"};
  29.     
  30. const char *shortWeekDays[7] = {"Sun", "Mon", "Tue", "Wed",
  31.                  "Thu", "Fri", "Sat"};
  32.                  
  33. const char *weekDays[7] = {"Sunday", "Monday", "Tuesday", "Wednesday",
  34.                  "Thursday", "Friday", "Saturday"};
  35.  
  36.  
  37. // 
  38. // Returns what day of the week in <year> will be. (0-6, 0=Sunday, 6= Saturday)
  39. //
  40. int jan1(int year)
  41. {
  42.  
  43.     int day;
  44.     
  45.     day = year + 4 + ((year +3) /4);
  46.     if( year > 1800) 
  47.         {
  48.         day -= ((year - 1701) / 100);
  49.         day += ((year - 1601) / 400);
  50.         }
  51.     if( year > 1752)
  52.         day += 3;
  53.     
  54.     return( day % 7);
  55. }
  56.  
  57. //
  58. // Returns how many days in the month for that year
  59. //
  60. int daysInMonth(int month, int year)
  61. {
  62.     return( ayear[month] - ayear[month-1] +
  63.         ((month == 2) ?
  64.             addOne(12,year) : 
  65.             0)); 
  66. }
  67.  
  68. //
  69. // Returns how many days will be in that year
  70. //
  71. int daysInYear(int year)
  72. {
  73.     return (365 + addOne(12, year));
  74. }
  75.  
  76.  
  77. //
  78. // Forgot
  79. //
  80. int addOne(int month, int year)
  81. {
  82.     if (month > 2) 
  83.         return( !(year % 4) - !(year%100) + !(year%400));
  84.     else
  85.         return 0;
  86. }
  87.  
  88. int daysUpTo( int month, int year)
  89. {
  90.     return(  ayear[month-1] + addOne(month, year)); 
  91. }
  92.  
  93.  
  94. int firstDayOf(int month, int year)
  95. {    
  96.     return ( (jan1(year) +   ayear[month-1] + 
  97.             addOne(month, year) ) %7);
  98. }
  99.     
  100.  
  101. int wday(int day, int month, int year)
  102. {    
  103.     return(     ( firstDayOf(month, year)  + day -1)   % 7);
  104. }
  105.  
  106.  
  107. int  yday(int day, int month, int year)
  108. {
  109.     return(    daysUpTo(month, year) + day -1);
  110. }
  111.  
  112.  
  113. int printCalendar( int month, int year, NXStream *stream)
  114. {
  115.     int count, tmp, daysIn;
  116.     
  117.     NXPrintf(stream, "     %s %d\n",months[month -1], year);
  118.     NXPrintf(stream, " S  M Tu  W Th  F  S\n");
  119.     
  120.     for( count = firstDayOf(month, year); count > 0; count --)
  121.         NXPrintf(stream, "   ");
  122.         
  123.     for( count = 1; count < 8- firstDayOf(month, year); count ++)
  124.         NXPrintf(stream, "%2d ", count);
  125.     
  126.     daysIn = daysInMonth(month, year);
  127.     
  128.     for(;;)
  129.         {
  130.         NXPrintf(stream, "\n");
  131.         for(tmp =0; tmp < 7; tmp++)
  132.             {
  133.             NXPrintf(stream, "%2d ",count++);
  134.             if( count > daysIn)
  135.                 return 1;
  136.             }
  137.         }
  138. }
  139.  
  140. int printCalendarRTF( int day, int month, int year, NXStream *stream, 
  141.             char *fontName, float fontSize)
  142. {
  143.     int count, tmp, daysIn;
  144.     
  145.     NXPrintf(stream, "{\\rtf0\\ansi{\\fonttbl\\f0\\fmodern %s;}\\fs%.0f\n",
  146.             fontName, fontSize * 2);
  147.     NXPrintf(stream, "{\\f0\\b      %s %d\\par}\n",months[month -1], year);
  148.     NXPrintf(stream, "{\\f0\\b  S  M Tu  W Th  F  S\\par}\n");
  149.     
  150.     NXPrintf(stream, "{\\f0 ");
  151.     
  152.     for( count = firstDayOf(month, year); count > 0; count --)
  153.         NXPrintf(stream, "   ");
  154.         
  155.     for( count = 1; count < 8- firstDayOf(month, year); count ++)
  156.         if( count == day)
  157.             NXPrintf(stream,     "}\n"
  158.                         "{\\f0\\b\\i\\ul %2d}\n"
  159.                         "{\\f0  ", count);
  160.         else
  161.             NXPrintf(stream,"%2d ", count);
  162.  
  163.     
  164.     daysIn = daysInMonth(month, year);
  165.     
  166.     for(;;)
  167.         {
  168.         NXPrintf(stream,    "\\par}\n"
  169.                 "{\\f0 ");
  170.         for(tmp =0; tmp < 7; tmp++)
  171.             {
  172.             if( count == day)
  173.                 NXPrintf(stream,     "}\n"
  174.                     "{\\f0\\b\\i %2d }\n"
  175.                     "{\\f0\\plain ", count++);
  176.             else
  177.                 NXPrintf(stream,"%2d ", count++);
  178.         
  179.             if( count > daysIn)
  180.                 {
  181.                 NXPrintf(stream, "}\n");
  182.                 return 1;
  183.                 }
  184.             }
  185.         }
  186.         
  187. }
  188.  
  189. const char *
  190. ascMyTime(struct tm * now, BOOL  showSeconds, BOOL militaryTime)
  191. {
  192.     static char string[64];
  193.     int hour;
  194.     char *timeMark;
  195.  
  196.     hour = now-> tm_hour;
  197.  
  198.     if( militaryTime)
  199.         timeMark = "";
  200.     else
  201.         {
  202.         if( hour > 11)
  203.             timeMark = "pm";
  204.         else
  205.             timeMark = "am";
  206.             
  207.         if( hour  > 12)
  208.             hour -= 12;
  209.         if( hour == 0)
  210.             hour = 12;
  211.         }
  212.  
  213.     if( showSeconds)
  214.         {
  215.         sprintf(string, "%s %s %2d, %4d   %2d:%02d:%02d %s", 
  216.             shortWeekDays[now->tm_wday],
  217.             shortMonths[now->tm_mon], now->tm_mday,
  218.             1900+now->tm_year, hour,
  219.             now-> tm_min, now-> tm_sec, 
  220.             timeMark);
  221.         }
  222.     else
  223.         {
  224.         sprintf(string, "%s %s %2d, %4d   %2d:%02d %s", 
  225.             shortWeekDays[now->tm_wday],
  226.             shortMonths[now->tm_mon], now->tm_mday,
  227.             1900+now->tm_year, hour,
  228.             now-> tm_min, 
  229.             timeMark );
  230.         }
  231.  
  232.     return( string);
  233. }
  234.  
  235.  
  236. const char *ascMyDate(struct tm * now)
  237. {
  238.     static char string[32];
  239.  
  240.     sprintf(string, "%s %s %2d, %4d", 
  241.         shortWeekDays[now->tm_wday],
  242.         shortMonths[now->tm_mon], now->tm_mday, 1900+now->tm_year);
  243.     return( string);
  244. }
  245.  
  246.  
  247.  
  248. int monthFromAscii(char *string)
  249. {
  250.     int a, atoi( char*);
  251.     
  252.     a = atoi( string);
  253.     if( a <= 12 && a >= 1)    /* If string is a valid integer for a month */
  254.         return a;
  255.     
  256.     for( a = 0; a < 12; a++)
  257.         {
  258.         if( calAsciiCmp( string, (char *) shortMonths[a]) == 0)
  259.             return(a+1);
  260.         }
  261.     NXRunAlertPanel("Invalid Number", "Sorry, I could not recognize the "
  262.             "month in the date you just typed. Could you please "
  263.             "retype it? It should be a number from 1-12 or the "
  264.             "name of a month, `Jan', `Feb', etc.",
  265.             "OK",NULL,NULL);
  266.     return 0;
  267. }
  268.     
  269.     
  270.  
  271. int calAsciiCmp( char *a , char *b)        
  272. {
  273.     int index;
  274.     char a1, b1;
  275.     
  276.     for( index = 0; index < 3; index ++)
  277.         {
  278.         a1 = * a++;
  279.         b1 = * b++;
  280.         
  281.         if( isupper(a1))
  282.             a1 = tolower( a1);
  283.             
  284.         if( isupper(b1))
  285.             b1 = tolower(b1);
  286.         
  287.         if( a1 == b1)
  288.             continue;
  289.             
  290.         if( a1 < b1)
  291.             return -1;
  292.         
  293.         if( a1 > b1)
  294.             return 1;
  295.         }
  296.     return 0;
  297. }
  298.     
  299. //
  300. // secondsBetween  - number of seconds between two date/times
  301. //
  302. double secondsBetween( struct tm * a, struct tm* b)
  303. {
  304.     double fromA, fromB;
  305.     int     flip, carryYear;
  306.  
  307.     #ifdef DEBUG
  308.         fprintf(stderr,"Calculating the seconds between A <%s> ",
  309.             ascMyTime( a, SEC, FALSE));
  310.         fprintf(stderr," and B <%s>.\n", ascMyTime( b, SEC, FALSE));
  311.     #endif
  312.  
  313.  
  314.     /* Initialize values to 0 */
  315.     fromA = fromB = 0.0;
  316.  
  317.     /* See if a is less than b, timeCompare does it, but */
  318.     /* we need to negate its value */
  319.     flip = - timeCompare( a, b);
  320.  
  321.     /* If the two times are the same, then return 0 seconds */
  322.     if( flip == 0)
  323.         return 0;
  324.  
  325.     /* If a is not less than b, than we need to flip a and b and */
  326.     /* remember that at the very end */
  327.     if( flip == -1)
  328.         {
  329.         struct tm temp;
  330.  
  331.         #ifdef DEBUG
  332.             fprintf(stderr, "Flipping a and b.\n");
  333.         #endif
  334.     
  335.         temp = *a;
  336.         *a = *b;
  337.         *b = temp;
  338.         }
  339.     
  340.     /* Calculate the number of seconds from Jan 1st of <a>'s year */
  341.     /* to <a> itself */
  342.     fromA = (double) (yday(    a->tm_mday, a-> tm_mon+1, 
  343.                 a-> tm_year + 1900) * (24 * 60 * 60))
  344.                 + (a-> tm_hour) * (60 * 60) 
  345.                 + ( a-> tm_min * 60) + a-> tm_sec;
  346.  
  347.     /* Calculate the number of years seperating <a> from <b> */
  348.     /* and add them to fromA */
  349.     for( carryYear = a-> tm_year; carryYear < b-> tm_year; carryYear++)
  350.         {
  351.         #ifdef DEBUG
  352.             fprintf(stderr,"Adding %d more days to fromB.\n",
  353.                 daysInYear(carryYear+1900));
  354.         #endif
  355.     
  356.         fromB += (double) (daysInYear(carryYear+1900)    
  357.             * (24 * 60 * 60));    /* times seconds in a day */
  358.         }
  359.  
  360.     /* Calculate the number of secons from Jan 1st of */
  361.     /* <b>'s year up to <b> itself */    
  362.     fromB += (double) (yday(b->tm_mday, 
  363.                 b-> tm_mon+1, 
  364.                 b-> tm_year + 1900) * (24 * 60 * 60))
  365.                 + (b-> tm_hour) * (60 * 60) 
  366.                 + ( b-> tm_min * 60) + b-> tm_sec;
  367.  
  368.     #ifdef DEBUG
  369.         fprintf(stderr, 
  370.         "Seconds between %6.1f and %6.1f are %f (%6.1f min.).\n"
  371.         "%d days.\n",
  372.         fromA, fromB, (fromB - fromA)*flip, (fromB-fromA)*flip/60,
  373.         (int) ((fromB - fromA)*flip) / ( 24*60*60) );
  374.     #endif
  375.     
  376.     /* Return the difference of the two, also flipping the */
  377.     /* minus sign if b happened to lesser */
  378.     /* than a at the very beginning */
  379.     return(    (fromB - fromA ) * flip);
  380. }
  381.  
  382. //
  383. // timeCompare  - compare two time structures
  384. //
  385. // return -1 if t1 is smaller than t2
  386. // return 0 if they are the same
  387. // return 1 if t1 is larger than t2
  388.  
  389. int timeCompare(struct tm *first, struct tm *second)
  390. {
  391.     double          t1, t2;
  392.  
  393.     t1 = (double) (first->tm_year * 10000 + first->tm_mon * 100 
  394.             + first->tm_mday);
  395.     t2 = (double) (second->tm_year * 10000 + second->tm_mon * 100 
  396.             + second->tm_mday);
  397.  
  398.     #ifdef DEBUG
  399.         fprintf(stderr, "Comparing Dates: %3.0f and %3.0f....\n",
  400.                 t1, t2);
  401.     #endif
  402.  
  403.     if (t1 < t2)
  404.         return -1;
  405.     if (t1 > t2)
  406.         return 1;
  407.  
  408.     t1 = first->tm_hour * 100 + first->tm_min;
  409.     t2 = second->tm_hour * 100 + second->tm_min;
  410.     
  411.     #ifdef DEBUG
  412.         fprintf(stderr, "Comparing Times: %3.0f and %3.0f....\n\n",
  413.                 t1, t2);
  414.     #endif
  415.  
  416.     if (t1 < t2)
  417.         return -1;
  418.     if (t1 > t2)
  419.         return 1;
  420.  
  421.     return (0);
  422. }
  423.  
  424.  
  425. //
  426. // dayCompare  - compare two time structures
  427. // 
  428. // return -1 if t1 is smaller than t2
  429. // return 0 if they are the same
  430. // return 1 if t1 is larger than t2
  431. int dayCompare(struct tm *first, struct tm *second)
  432. {
  433.     double          t1, t2;
  434.  
  435.     t1 = (double) (first->tm_year * 10000 + first->tm_mon * 100 
  436.             + first->tm_mday);
  437.     t2 = (double) (second->tm_year * 10000 + second->tm_mon * 100 
  438.             + second->tm_mday);
  439.  
  440.     #ifdef DEBUG
  441.         fprintf(stderr, "Comparing Dates: %3.0f and %3.0f....\n",
  442.                 t1, t2);
  443.     #endif
  444.  
  445.     if (t1 < t2)
  446.         return -1;
  447.     if (t1 > t2)
  448.         return 1;
  449.     return (0);
  450. }
  451.  
  452. void fixTmStructure( struct tm *ts)
  453. {
  454.     int temp;
  455.     
  456.     
  457.     /* We must go around twice, first to check negative and 
  458.        then to check positive overflows */
  459.  
  460.     /* First check seconds */
  461.     while( ts->tm_sec < 0)
  462.         {
  463.         ts->tm_sec += 60;
  464.         ts->tm_min --;
  465.         }
  466.         
  467.     /* Then minutes */
  468.     while( ts->tm_min < 0)
  469.         {
  470.         ts->tm_min += 60;
  471.         ts->tm_hour--;
  472.         }
  473.     
  474.     /* Then hours */
  475.     while( ts->tm_hour < 0)
  476.         {
  477.         ts -> tm_hour += 24;
  478.         ts -> tm_mday --;
  479.         }
  480.     
  481.     /* Then days (gets a bit more difficult now) */
  482.     while( ts-> tm_mday < 1)
  483.         {
  484.         ts -> tm_mon --;
  485.         if( ts-> tm_mon < 0)
  486.             {
  487.             ts-> tm_mon += 12;
  488.             ts-> tm_year --;
  489.             }
  490.             
  491.         ts -> tm_mday += daysInMonth( ts->tm_mon+1, ts->tm_year+ 1900);
  492.         }
  493.     
  494.     /* Then months */
  495.     if( ts-> tm_mon < 0 )
  496.             {
  497.             ts-> tm_mon += 12;
  498.             ts-> tm_year --;
  499.             }
  500.             
  501.     /* Then years */
  502.     if( ts->tm_year < 0)
  503.         ts->tm_year = 0;
  504.         
  505.         
  506.     /* First check seconds */
  507.     while( ts->tm_sec > 59)
  508.         {
  509.         ts->tm_sec -= 60;
  510.         ts->tm_min ++;
  511.         }
  512.         
  513.     /* Then minutes */
  514.     while( ts->tm_min > 59)
  515.         {
  516.         ts->tm_min -= 60;
  517.         ts->tm_hour++;
  518.         }
  519.     
  520.     /* Then hours */
  521.     while( ts->tm_hour > 23)
  522.         {
  523.         ts -> tm_hour -= 24;
  524.         ts -> tm_mday ++;
  525.         }
  526.     
  527.     /* Then days (gets a bit more difficult now) */
  528.     temp = daysInMonth( ts->tm_mon +1, ts->tm_year+ 1900);
  529.     while( ts-> tm_mday > temp)
  530.         {
  531.         ts -> tm_mday -= temp;
  532.         ts -> tm_mon ++;
  533.         if( ts-> tm_mon > 11)
  534.             {
  535.             ts-> tm_mon -= 12;
  536.             ts-> tm_year ++;
  537.             }
  538.         temp = daysInMonth( ts->tm_mon +1, ts->tm_year+ 1900);
  539.         }
  540.     
  541.     /* Then months (easy and last) */
  542.     if( ts-> tm_mon > 11)
  543.             {
  544.             ts-> tm_mon -= 12;
  545.             ts-> tm_year ++;
  546.             }
  547.     
  548.     /* Fix up wday and yday and we're done! */
  549.     ts->tm_wday = wday( ts->tm_mday, ts-> tm_mon + 1, ts-> tm_year + 1900);
  550.     ts->tm_yday = yday( ts->tm_mday, ts-> tm_mon + 1, ts-> tm_year + 1900);
  551.  
  552.     /* All done, now we return :) */
  553.     return;
  554. }
  555.     
  556. const struct tm * timeNow()
  557. {
  558.     static struct tm time_now;
  559.     struct tm *localtime();
  560.     time_t time(), var;
  561.  
  562.     var = time(0);
  563.     time_now = *localtime(&var); 
  564.     return( &time_now);
  565. }
  566.