The Month Program, Phase IV

Last week’s Lesson demonstrates a pretty decent calendar program. It works for every month of the year that has 31 days. Obviously that’s not every month, so more fine tuning must be done, especially to deal with the variable number of days in February.

Dates and times are two things that can utterly infuriate a programmer. Unlike so much other data, the calendar just isn’t logical: A year has 365 days 75 percent of the time. Eleven of the 12 months feature discrete days. February fluctuates between 28 and 29 days. Leap years are every four years, unless the year is divisible by 100 but not 400.

Got it?

To make a calendar program work, you need to craft a function that properly calculates the number of days in February for a given year. On the positive side, rules exist for determining that calculation, so your task is to code those rules. Here are the rules:

  • If the year is divisible by 4, it’s a leap year. February has 29 days. Otherwise, February has 28 days.
  • If the leap year is divisible by 100, then it’s not a leap year and February has 28 days, unless:
  • If the leap year is divisible by both 100 and 400, then February has 29 days.

There. Cinchy.

The following code contains the february() function. It’s passed a year value y and then it uses way too many modulus calculations to return either the value 28 for non-leap years or 29 for a leap year.

The rest of the code simply plows through the months of the current year, displaying their discrete number of days.

#include <stdio.h>
#include <time.h>

int february(int y);

int main()
{
	char *months[12] = {
		"January", "February", "March", "April",
		"May", "June", "July", "August",
		"September", "October", "November", "December" };
	int month_length[] = {
		31, 28, 31, 30, 31, 30,
		31, 31, 30, 31, 30, 31 };
	time_t tictoc;
	struct tm *rightnow;
	int x,year;

	time(&tictoc);
	rightnow = localtime(&tictoc);
	year = rightnow->tm_year + 1900;

	month_length[1] = february(year);

	printf("For %d:\n",year);
	for(x=0;x<12;x++)
		printf("%s has %d days\n",
			months[x],
			month_length[x]);

	return(0);
}

int february(int y)
{
	if( y % 4 )
		return(28);
	if( !(y % 100))
	{
		if( y % 400 )
			return(28);
		else
			return(29);
	}
	return(29);
}

Here’s sample output, which is relevant to the current year, 2014:

For 2014:
January has 31 days
February has 28 days
March has 31 days
April has 30 days
May has 31 days
June has 30 days
July has 31 days
August has 31 days
September has 30 days
October has 31 days
November has 30 days
December has 31 days

To incorporate this code into a calendar program, I’ve made some modifications. Specifically, you don’t really need a february() function for a calendar program as much as you need a function that returns the number of days in any month for a given year. That function, daysInMonth(), is demonstrated in the following code:

#include <stdio.h>
#include <time.h>

int daysInMonth(int month,int year);

int main()
{
	char *months[12] = {
		"January", "February", "March", "April",
		"May", "June", "July", "August",
		"September", "October", "November", "December" };
	time_t tictoc;
	struct tm *rightnow;
	int x,year;

	time(&tictoc);
	rightnow = localtime(&tictoc);
	year = rightnow->tm_year + 1900;

	printf("For %d:\n",year);
	for(x=0;x<12;x++)
		printf("%s has %d days\n",
			months[x],
			daysInMonth(x,year));

	return(0);
}

int daysInMonth(int month,int year)
{
	int month_length[] = {
		31, 28, 31, 30, 31, 30,
		31, 31, 30, 31, 30, 31 };

	if(month != 1)
		return(month_length[month]);

	if( year % 4 )
		return(28);
	if( !(year % 100))
	{
		if( year % 400 )
			return(28);
		else
			return(29);
	}
	return(29);
}

The daysInMonth() function eats two arguments: The month and year. The month is value from 0 through 11 for January through December. This function works it way into the calendar program, supplying the proper number of days of the month for whichever month is being displayed. You’ll see how that all wraps up with next week’s final installment for this series of Lessons.

Leave a Reply