/******************************************************************************/
/* Calendar Program - 16.1.89 - A. Johnson /
/* This program
"Cal" when run from CLI will generate Calendars for any /
/* Month or year. It emulates the UNIX command "cal"
(surprise, surprise) /
/* in this respect. Uses "Zeller's date congruence"
function to calculate /
/* days of week for first day of month. /
/******************************************************************************/
/******************************************************************************
Operation:
When compiled
and run, the user can type "cal 1992" for a calendar listing
of 1992, or "cal
3 1992" for a calendar of March 1992.
The program
first gets the command line arguments, then calls
a funtion to
initialize a data array. This function calls the
"zeller_day_no"
function to get the day number (0 to 6) for the first
day of each
month. This is then used as a starting point for the calendar
for that
month.
When run, re-direction
can be used to put the output of this program to
the printer, or
to a file.
*****************************************************************************/
/* Include 2 of the standard C header files for the
functions / definitions
we will be using. */
#include <stdio.h>
#include <stdlib.h>
/******************
Data for building up calendar *******************/
/* We will
print the calendar out in a 3 x 4 grid of months. */
/* We will
print out 3 months at "a time". /
/* A month
can spread across 6 weeks! /
/* Declare an
array to hold 3 months' worth of days. */
int month_array[3][7][6] = {0};
/* Declare an
array to hold the days in each month. */
int days_in_month[12] = {
31, /*
Jan */
28, /*
Feb */
31, /*
Mar */
30, /*
Apr */
31, /*
May */
30, /*
Jun */
31, /*
Jul */
31, /*
Aug */
30, /* Sep */
31, /*
Oct */
30, /* Nov */
31 /* Dec */
};
/* Declare
some working variables. */
int working_month, working_year, leap_day;
/* Declare an
array of strings for the days of the week */
char day_string[7]={
"Sun",
"Mon", "Tue", "Wed",
"Thu",
"Fri", "Sat"
};
/* Declare an
array of strings for the months of the year. */
char months[12]= {
"Jan",
"Feb", "Mar", "Apr", "May", "Jun",
"Jul",
"Aug", "Sep", "Oct", "Nov", "Dec"
};
/*****************************************************************************
* Function: zeller_day_no
* Description: Gives
the number of the day of the week for the given date.
* Parameters: int day - date, int month - month no, int
year - AD year
* Returns: day
of week as an int in range 0 to 6, 0
being Sunday.
******************************************************************************/
int zeller_day_no (int day, int month, int year)
{
int temp, yr1,
yr2;
/* Now do
Zeller's jiggery pokery with the numbers to work out a
day number from the day, month and year
parameters. */
if (month <
3)
{
month += 10;
year -= 1;
}
else month -=2;
yr1 = year / 100;
yr2 = year % 100;
temp = (26 * month
- 1)/10;
return ((day +
temp + yr2 + yr2/4 + yr1/4 - 2 * yr1 +49)%7);
}
/*****************************************************************************
* Function: do_months
* Description: Fills
up the "month array" with day values.
* Parameters: int - month number, int - year number int - no.
of months
* Returns: nothing
******************************************************************************/
void do_months (int month, int year, int no_of_months)
{
int temp_day,
day_no, week_number,i;
/* Do for the
specified number of months. */
for (i=0; i <
no_of_months; i++)
{
/* Get the number of the day for the first
day of the month. */
day_no = zeller_day_no (1, month+i+1, year);
/* Initialize array at beginning and end to
stop overlap problems later. */
for (temp_day = 0; temp_day <= 6; temp_day++)
{
/* Use
multiple assignment. */
month_array[i][temp_day][0] = month_array[i][temp_day][4]=
month_array[i][temp_day][5] = 0;
}
/* Initialise a "week in month" counting
variable. */
week_number = 0;
/* Now just put the day numbers in the
month array, picking out the
number
of days in the month from "days_in_month". */
for (temp_day = 1; temp_day <= (days_in_month[month+i]);
temp_day++)
{
/*
Initialise the array element. */
month_array[i][day_no][week_number]
= temp_day;
/*
Increment the day number. */
day_no
++;
/*
Now we do "MOD 7" to make the day number always go round from
0 to 6 */
day_no
%= 7;
/*
Check if "day no" wrapped round - if so, we increment the week
counter. */
if (day_no == 0)
{
/* Move to the next week. */
week_number++;
}
}
}
}
/*****************************************************************************
* Function: print_months
* Description: Prints
out the specified number of months using the data in *
* "month array".
* Parameters: int - month number, int - no. of months
* Returns: nothing
******************************************************************************/
void print_months(int month, int no_of_months)
{
int weekday, week_number, month_no;
/* Print out the month titles. */
for (month_no = month; month_no < month + no_of_months;
month_no++)
{
/* Print
the months name first. */
printf ("%14s ", months[month_no]);
}
/* When we are just printing a single month, show
the year also. */
if (no_of_months == 1)
{
printf ("\n\n%14d", working_year);
}
/* Print a carriage return or 2. */
printf ("\n\n");
/* Print out a given day of the week for each
month e.g. print all
the
Sundays, then all the Mondays etc. */
/* Do each weekday... */
for (weekday = 0; weekday <= 6; weekday++) /* Start at Sunday */
{
/*
... for each month... */
for
(month_no = 0; month_no < no_of_months; month_no++)
{
printf (" %s", day_string[weekday]); /* Print
the day. /
/* ... do each week. */
for (week_number = 0; week_number <= 5; week_number++)
{
/*
We are only going to print non-zero elements of the array. */
if
(month_array[month_no][weekday][week_number])
{
printf ("%3d", month_array[month_no][weekday][week_number]);
}
else
{
printf (" ");
/*
... print spaces instead. */
}
}
printf (" "); /* End of month - space out. */
}
printf ("\n"); /* End of months - next line.*/
}
printf("\n\n"); /* End of months' block. /
}
/******************************************************************************/
/* The Main program! /
/******************************************************************************/
/* The arguments to main are used to access what was
typed on the command line. */
void main (int argument_count, char **argument_table_ptr)
{
int temp_month,
end_month, no_of_months;
printf ("\n");
/************************************************************************
The following works out whether we will print
out a single month from *
the year (2 arguments) or the whole year (1
argument passed).
The months are then printed out in blocks.
************************************************************************/
/* Check the
number of arguments which were typed on the command line. */
if ((argument_count==1)
|| (argument_count > 3))
{
printf ("CAL V1.1 Calendar Generator\n\n");
printf ("Usage:\tCal [month no.] Year \te.g.\n");
printf ("\tCal 1992 \t\tfor a calendar of
1992.\n");
printf ("\tCal 1 1993 \t\tfor a calendar
of January 1993.\n");
}
else
{
/* When the argument count is 2, we want to
do a Whole Year! */
if (argument_count == 2)
{
/* Get
the year as typed on the command line. */
/* This
is a string so we have to convert it to an integer using
"atoi". */
working_year = atoi (*++argument_table_ptr);
/* Set the last month we wish to do. */
end_month
= 12;
/* We
are going to do it in 3 month blocks. */
no_of_months
= 3;
/* Start
in month 1 - January. */
working_month = 1;
/* Print
a prompt. */
printf ("%30sCalendar for %d\n\n"," ",working_year);
}
else /* A month and year has been specified.
*/
{
/*
Get the month from the command line and convert it to "int". */
working_month
= atoi (*++argument_table_ptr);
/*
Get the year from the command line and convert it to "int". */
working_year = atoi (*++argument_table_ptr);
/*
We are only going to do this month. */
end_month
= working_month;
/*
We do just one month. */
no_of_months
= 1; /*
Only 1 month to do! /
}
/* Now we are going to check a valid month
number has been typed. */
if ((working_month < 1) || (working_month
> 12))
{
printf
("\n\n***Invalid Month number!***\n\n");
}
else
{
/*
Have we got a Leap year situation? (This is the full formula.) */
if
(((working_year % 4) == 0) && ((working_year % 100) != 0) ||
((working_year % 400) == 0))
{
/* Re-initialize
February in "days in month" to have 29 days! */
days_in_month[1]
= 29;
}
}
/* Do calendar for the specified number of
months. /
/* This will print out the months in blocks
of 3 or 1. */
for (temp_month = working_month; temp_month
<= end_month; temp_month += no_of_months)
{
/* Now do the business... */
/* Initialise the months array. */
do_months
(temp_month - 1, working_year, no_of_months);
/* Print out the data. */
print_months(temp_month - 1, no_of_months);
}
}
}
No comments:
Post a Comment