The Whole Month from a Single Day – Solution

The key to creating a calendar is to know on which day of the week the first of the month falls. This datum can be extrapolated from any other day of the month, as long as you know on which day of the week it falls.

If you look at a calendar, such as the one shown in Figure 1, you see how each day of the month has a corresponding day on the first week of the month. This pattern is consistent, so when the dates shift around, the first of the month shifts as well. The key to unlocking this month’s Exercise is to calculate the relationship between each day of the month and the first day.

Figure 1. A typical month.

To determine the first day of the month you need only two tidbits of information: the number of some other day of the month and the day of the week upon which it falls. These are the identical arguments to the month() function for the Exercise:

void month(int day, int weekday)

The weekdays are supplied as enumerated constants, values 0 through 6:

enum { SUN, MON, TUE, WED, THU, FRI, SAT };

Using the sample calendar from Figure 1, suppose you have that the 17th of the month is on a Friday (FRI or 6). Here’s the math I use to calculate the first:

first = weekday - ( day % 7 ) + 1;

Which works out as:

first = 6 - ( 17 % 7 ) + 1;
first = 6 - ( 3 ) + 1;
first = 4;

So the first of the month is on weekday 4, WED or Wednesday. And if you look at Figure 1, the answer is correct.

If you’re given the 13th, which is a Monday, here’s the math:

first = 1 - ( 13 % 7 ) + 1;
first = 1 - ( 5 ) + 1;
first = -3;

The value -3 doesn’t translate into a day of the week that’s in range. Perhaps it’s Blurnsday, but until the Galactic Calendar Reform of 2622 arrives, more programming is necessary to determine upon which day of the week the first falls:

if( first < 0 )
    first+=7;

The result of -3 + 7 is 4, which is Wednesday, the proper day of the week upon with the first of the month falls.

Once you know the first day of the month and its weekday, the month’s calendar can be output in a loop:

#include <stdio.h>
/* Display the month */
    puts("Sun Mon Tue Wed Thu Fri Sat");
    monthday = 1;
    while(monthday < 31)
    {
        /* display a week */
        for(dow=0;dow<7;dow++)
        {
            /* don't display dates before the first */
            if(dow<first && monthday==1)
            {
                printf("    ");        /* 4 spaces */
            }
            else
            {
                printf(" %2d ",monthday);
                monthday++;
                if(monthday > 30)
                    break;
            }
        }
        putchar('\n');
    }

The outer while loop works by days of the month, which are fixed at 30 for this Exercise. The inner for loop displays each successive week of the month. Two if tests inside the for loop prevent days before the first and days after the 30th from being displayed.

Click here to view the full code for my solution.

I hope your solution met with success. I assume other ways exist to populate a month full of dates based only a single day of the month and its day of the week. Your solution can be expanded to build a full-calendar app: Instead of using preset days and weekdays, use a time function to obtain the current date and then build your month. Or, if your ambitious, build an entire year!

Leave a Reply