This is calendar.m in view mode; [Download] [Up]
//
// calendar.m
// Copyright (c) 1989, 1990 by Jiro Nakamura
// All rights reserved
//
// Calendar routine package.
//
// RCS Information
// Revision Number-> $Revision: 2.7 $
// Last Revised-> $Date: 91/12/20 14:04:59 $
//
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 $";
#import <stdio.h>
#import <c.h>
#import <ctype.h>
#import <appkit/Panel.h> /* for NXRunAlertPanel */
#import "calendar.h"
#import "misc.h"
const int ayear[13] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273,
304, 334, 365};
const char *months[12]= {"January", "February", "March", "April", "May",
"June", "July","August","September",
"October","November","December"};
const char *shortMonths[12] ={"Jan", "Feb", "Mar", "Apr", "May",
"Jun", "Jul", "Aug", "Sep",
"Oct", "Nov", "Dec"};
const char *shortWeekDays[7] = {"Sun", "Mon", "Tue", "Wed",
"Thu", "Fri", "Sat"};
const char *weekDays[7] = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"};
void dumbRcsidReference()
{
char dumbChar[5];
// dumb references to some static constants, just
// to avoid warning messages from the compiler (Garance)
dumbChar[0] = rcsid[0]; // dumb de dumb
return;
}
//
// Returns what day of the week in <year> will be. (0-6, 0=Sunday, 6= Saturday)
//
int jan1(int year)
{
int day;
day = year + 4 + ((year +3) /4);
if( year > 1800)
{
day -= ((year - 1701) / 100);
day += ((year - 1601) / 400);
}
if( year > 1752)
day += 3;
return( day % 7);
}
//
// Returns how many days in the month for that year
// # Have to watch out, because sometimes we're called with
// # a value for month that's out-of-range. Sigh. Also note
// # that we're expecting a range of 1-12, not 0-11 like all
// # other month-related routines would do. My My. Need some
// # contract-based programming here (as in, Eiffel-style).
// # Garance/Dec 22/95
//
int daysInMonth(int month, int year)
{
int validMonth = month;
int validYear = year;
int res, tempRes;
while ( validMonth < 1 ) {
validMonth +=12;
validYear--;
}
while ( validMonth > 12 ) {
validMonth -=12;
validYear++;
}
res = ayear[validMonth] - ayear[validMonth-1];
if (month == 2) {
res += addOne(12, validYear);
}
// Having been burnt by this routine, let's add some
// extreme sanity checks! Garance.
tempRes = res;
if ( res < 28 ) res = 28;
if ( res > 31 ) res = 31;
if ( res != tempRes ) {
fprintf(stderr, "Cassandra: daysInMonth(m=%d,y=%d) nearly "
"came up with result of %d! (will use %d)\n",
month, year, tempRes, res);
}
return( res );
}
//
// Returns how many days will be in that year
//
int daysInYear(int year)
{
return (365 + addOne(12, year));
}
//
// Forgot
//
int addOne(int month, int year)
{
if (month > 2)
return( !(year % 4) - !(year%100) + !(year%400));
else
return 0;
}
int daysUpTo( int month, int year)
{
return( ayear[month-1] + addOne(month, year));
}
int firstDayOf(int month, int year)
{
return ( (jan1(year) + ayear[month-1] +
addOne(month, year) ) %7);
}
int wday(int day, int month, int year)
{
return( ( firstDayOf(month, year) + day -1) % 7);
}
int yday(int day, int month, int year)
{
return( daysUpTo(month, year) + day -1);
}
int printCalendar( int month, int year, NXStream *stream)
{
int count, tmp, daysIn;
NXPrintf(stream, " %s %d\n",months[month -1], year);
NXPrintf(stream, " S M Tu W Th F S\n");
for( count = firstDayOf(month, year); count > 0; count --)
NXPrintf(stream, " ");
for( count = 1; count < 8- firstDayOf(month, year); count ++)
NXPrintf(stream, "%2d ", count);
daysIn = daysInMonth(month, year);
for(;;)
{
NXPrintf(stream, "\n");
for(tmp =0; tmp < 7; tmp++)
{
NXPrintf(stream, "%2d ",count++);
if( count > daysIn)
return 1;
}
}
}
int printCalendarRTF( int day, int month, int year, NXStream *stream,
char *fontName, float fontSize)
{
int count, tmp, daysIn;
NXPrintf(stream, "{\\rtf0\\ansi{\\fonttbl\\f0\\fmodern %s;}\\fs%.0f\n",
fontName, fontSize * 2);
NXPrintf(stream, "{\\f0\\b %s %d\\par}\n",months[month -1], year);
NXPrintf(stream, "{\\f0\\b S M Tu W Th F S\\par}\n");
NXPrintf(stream, "{\\f0 ");
for( count = firstDayOf(month, year); count > 0; count --)
NXPrintf(stream, " ");
for( count = 1; count < 8- firstDayOf(month, year); count ++)
if( count == day)
NXPrintf(stream, "}\n"
"{\\f0\\b\\i\\ul %2d}\n"
"{\\f0 ", count);
else
NXPrintf(stream,"%2d ", count);
daysIn = daysInMonth(month, year);
for(;;)
{
NXPrintf(stream, "\\par}\n"
"{\\f0 ");
for(tmp =0; tmp < 7; tmp++)
{
if( count == day)
NXPrintf(stream, "}\n"
"{\\f0\\b\\i %2d }\n"
"{\\f0\\plain ", count++);
else
NXPrintf(stream,"%2d ", count++);
if( count > daysIn)
{
NXPrintf(stream, "}\n");
return 1;
}
}
}
}
const char *
ascMyTime(struct tm * now, BOOL showSeconds, BOOL militaryTime)
{
static char string[64];
int hour;
char *timeMark;
hour = now-> tm_hour;
if( militaryTime)
timeMark = "";
else
{
if( hour > 11)
timeMark = "pm";
else
timeMark = "am";
if( hour > 12)
hour -= 12;
if( hour == 0)
hour = 12;
}
if( showSeconds)
{
sprintf(string, "%s %s %2d, %4d %2d:%02d:%02d %s",
shortWeekDays[now->tm_wday],
shortMonths[now->tm_mon], now->tm_mday,
1900+now->tm_year, hour,
now-> tm_min, now-> tm_sec,
timeMark);
}
else
{
sprintf(string, "%s %s %2d, %4d %2d:%02d %s",
shortWeekDays[now->tm_wday],
shortMonths[now->tm_mon], now->tm_mday,
1900+now->tm_year, hour,
now-> tm_min,
timeMark );
}
return( string);
}
const char *ascMyDate(struct tm * now)
{
static char string[32];
sprintf(string, "%s %s %2d, %4d",
shortWeekDays[now->tm_wday],
shortMonths[now->tm_mon], now->tm_mday, 1900+now->tm_year);
return( string);
}
int monthFromAscii(char *string)
{
int a, atoi( char*);
a = atoi( string);
if( a <= 12 && a >= 1) /* If string is a valid integer for a month */
return a;
for( a = 0; a < 12; a++)
{
if( calAsciiCmp( string, (char *) shortMonths[a]) == 0)
return(a+1);
}
NXRunAlertPanel("Invalid Number", "Sorry, I could not recognize the "
"month in the date you just typed. Could you please "
"retype it? It should be a number from 1-12 or the "
"name of a month, `Jan', `Feb', etc.",
"OK",NULL,NULL);
return 0;
}
int calAsciiCmp( char *a , char *b)
{
int index;
char a1, b1;
for( index = 0; index < 3; index ++)
{
a1 = * a++;
b1 = * b++;
if( isupper(a1))
a1 = tolower( a1);
if( isupper(b1))
b1 = tolower(b1);
if( a1 == b1)
continue;
if( a1 < b1)
return -1;
if( a1 > b1)
return 1;
}
return 0;
}
//
// secondsBetween - number of seconds between two date/times
//
double secondsBetween( struct tm * a, struct tm* b)
{
double fromA, fromB;
int flip, carryYear;
#ifdef DEBUG
fprintf(stderr,"Calculating the seconds between A <%s> ",
ascMyTime( a, SEC, FALSE));
fprintf(stderr," and B <%s>.\n", ascMyTime( b, SEC, FALSE));
#endif
/* Initialize values to 0 */
fromA = fromB = 0.0;
/* See if a is less than b, timeCompare does it, but */
/* we need to negate its value */
flip = - timeCompare( a, b);
/* If the two times are the same, then return 0 seconds */
if( flip == 0)
return 0;
/* If a is not less than b, than we need to flip a and b and */
/* remember that at the very end */
if( flip == -1)
{
struct tm temp;
#ifdef DEBUG
fprintf(stderr, "Flipping a and b.\n");
#endif
temp = *a;
*a = *b;
*b = temp;
}
/* Calculate the number of seconds from Jan 1st of <a>'s year */
/* to <a> itself */
fromA = (double) (yday( a->tm_mday, a-> tm_mon+1,
a-> tm_year + 1900) * (24 * 60 * 60))
+ (a-> tm_hour) * (60 * 60)
+ ( a-> tm_min * 60) + a-> tm_sec;
/* Calculate the number of years seperating <a> from <b> */
/* and add them to fromA */
for( carryYear = a-> tm_year; carryYear < b-> tm_year; carryYear++)
{
#ifdef DEBUG
fprintf(stderr,"Adding %d more days to fromB.\n",
daysInYear(carryYear+1900));
#endif
fromB += (double) (daysInYear(carryYear+1900)
* (24 * 60 * 60)); /* times seconds in a day */
}
/* Calculate the number of secons from Jan 1st of */
/* <b>'s year up to <b> itself */
fromB += (double) (yday(b->tm_mday,
b-> tm_mon+1,
b-> tm_year + 1900) * (24 * 60 * 60))
+ (b-> tm_hour) * (60 * 60)
+ ( b-> tm_min * 60) + b-> tm_sec;
#ifdef DEBUG
fprintf(stderr,
"Seconds between %6.1f and %6.1f are %f (%6.1f min.).\n"
"%d days.\n",
fromA, fromB, (fromB - fromA)*flip, (fromB-fromA)*flip/60,
(int) ((fromB - fromA)*flip) / ( 24*60*60) );
#endif
/* Return the difference of the two, also flipping the */
/* minus sign if b happened to lesser */
/* than a at the very beginning */
return( (fromB - fromA ) * flip);
}
//
// timeCompare - compare two time structures
//
// return -1 if t1 is smaller than t2
// return 0 if they are the same
// return 1 if t1 is larger than t2
int timeCompare(struct tm *first, struct tm *second)
{
double t1, t2;
t1 = (double) (first->tm_year * 10000 + first->tm_mon * 100
+ first->tm_mday);
t2 = (double) (second->tm_year * 10000 + second->tm_mon * 100
+ second->tm_mday);
#ifdef DEBUG
fprintf(stderr, "Comparing Dates: %3.0f and %3.0f....\n",
t1, t2);
#endif
if (t1 < t2)
return -1;
if (t1 > t2)
return 1;
t1 = first->tm_hour * 100 + first->tm_min;
t2 = second->tm_hour * 100 + second->tm_min;
#ifdef DEBUG
fprintf(stderr, "Comparing Times: %3.0f and %3.0f....\n\n",
t1, t2);
#endif
if (t1 < t2)
return -1;
if (t1 > t2)
return 1;
return (0);
}
//
// dayCompare - compare two time structures
//
// return -1 if t1 is smaller than t2
// return 0 if they are the same
// return 1 if t1 is larger than t2
int dayCompare(struct tm *first, struct tm *second)
{
double t1, t2;
t1 = (double) (first->tm_year * 10000 + first->tm_mon * 100
+ first->tm_mday);
t2 = (double) (second->tm_year * 10000 + second->tm_mon * 100
+ second->tm_mday);
#ifdef DEBUG
fprintf(stderr, "Comparing Dates: %3.0f and %3.0f....\n",
t1, t2);
#endif
if (t1 < t2)
return -1;
if (t1 > t2)
return 1;
return (0);
}
void fixTmStructure( struct tm *ts)
{
int temp;
/* We must go around twice, first to check negative and
then to check positive overflows */
/* First check seconds */
while( ts->tm_sec < 0)
{
ts->tm_sec += 60;
ts->tm_min --;
}
/* Then minutes */
while( ts->tm_min < 0)
{
ts->tm_min += 60;
ts->tm_hour--;
}
/* Then hours */
while( ts->tm_hour < 0)
{
ts -> tm_hour += 24;
ts -> tm_mday --;
}
/* Then days (gets a bit more difficult now) */
while( ts-> tm_mday < 1)
{
ts -> tm_mon --;
if( ts-> tm_mon < 0)
{
ts-> tm_mon += 12;
ts-> tm_year --;
}
ts -> tm_mday += daysInMonth( ts->tm_mon+1, ts->tm_year+ 1900);
}
/* Then months */
if( ts-> tm_mon < 0 )
{
ts-> tm_mon += 12;
ts-> tm_year --;
}
/* Then years */
if( ts->tm_year < 0)
ts->tm_year = 0;
/* First check seconds */
while( ts->tm_sec > 59)
{
ts->tm_sec -= 60;
ts->tm_min ++;
}
/* Then minutes */
while( ts->tm_min > 59)
{
ts->tm_min -= 60;
ts->tm_hour++;
}
/* Then hours */
while( ts->tm_hour > 23)
{
ts -> tm_hour -= 24;
ts -> tm_mday ++;
}
/* Then days (gets a bit more difficult now) */
temp = daysInMonth( ts->tm_mon +1, ts->tm_year+ 1900);
while( ts-> tm_mday > temp)
{
ts -> tm_mday -= temp;
ts -> tm_mon ++;
if( ts-> tm_mon > 11)
{
ts-> tm_mon -= 12;
ts-> tm_year ++;
}
temp = daysInMonth( ts->tm_mon +1, ts->tm_year+ 1900);
}
/* Then months (easy and last) */
if( ts-> tm_mon > 11)
{
ts-> tm_mon -= 12;
ts-> tm_year ++;
}
/* Fix up wday and yday and we're done! */
ts->tm_wday = wday( ts->tm_mday, ts-> tm_mon + 1, ts-> tm_year + 1900);
ts->tm_yday = yday( ts->tm_mday, ts-> tm_mon + 1, ts-> tm_year + 1900);
/* All done, now we return :) */
return;
}
const struct tm * timeNow()
{
static struct tm time_now;
struct tm *localtime();
time_t time(), var;
var = time(0);
time_now = *localtime(&var);
return( &time_now);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.