Calendar Math


Calendars are sometimes the most difficult thing to design. I think the main reason is the complex set of variables that are needed to be handled. With each month comes a different number of days, a different starting day is always an obstacle too. Another difficult situation to some is the previous days in the first week (prior month) and then the days that are in the remaining days in the last week (next month’s days). Sometimes we tend to over think certain programming tasks. We think about how difficult it will be to figure all of these things out at once to make the perfect calendar. This leads me to the creation of this article, a simple way to use math to develop a calendar.
Instead of thinking about the complex functions and algorithms we’ll use to make the calendar, we’ll focus on the simple math that logically unveils itself in every day, week, month, and even year. In this example I will use PHP (but event the novice program should be able to adapt this calendar to any programming language). Lets first start by defining a few simple things we’ll need to know with the following code:


$current_month = date('m');
$current_year = date('Y');
$num_days_in_last_month = (($current_month == 1) ? date('t', mktime(0,0,0,12,1,$current_year-1)) : date('t', mktime(0,0,0,$current_month-1,1,$current_year)));
$num_days_in_this_month = date('t', mktime(0,0,0,$current_month,1,$current_year));
$index_of_last_day_of_last_month = (($current_month == 1) ? date('w', mktime(0,0,0,12,$num_days_in_last_month,$current_year-1)) : date('w', mktime(0,0,0,$current_month-1,$num_days_in_last_month,$current_year)));
$num_days_in_month = $num_days_in_last_month;
$offset = $num_days_in_month - $index_of_last_day_of_last_month - 1;
$curr_month = ($current_month + 10)%12 + 1;
$curr_year = (($current_month == 1) ? $current_year-1 : $current_year);

Above we are simply defining each part of the mathematical formula we will use to design our calendar.
While I am using the php functions to define that we will use the current month and the current year, simple fixed variables could also be used.
Example for August 2008 Calendar Display:


$current_month = 8;
$current_year = 2008;

You will also see that in order for this to work we’ll need to know a few things (number of days in the previous month, number of days in the month, etc). We will also need to know the index of the last day in the month. This will be a number 0 – 6 representing the week day that the last month ended on (0 being sunday, 1 being monday and so forth). Since we will be using a few simple nested loops to create our calendar we’ll first want to start by rewinding back to the first day we will see on our calendar. At first I had a bit of trouble figuring out how far to go, but then after a little research realized that the most weeks that could ever be in one calendar month was 6. In this example if there happens to only be 4 weeks [Feb. 2009] (when the current month starts on Sunday and ends on the 4th Saturday) we will simply show the whole last week of the previous month on the calendar and the whole first week of the next month. Finally, we see a rather strange piece of code that ties the rest together:

($current_month + 10)%12 + 1;

Let’s take this code and analyze it. We will assume 8 is the value of $current_month. 8 + 10 = 18
18%12 = 6
This is because we are taking the current month adding 10 to it so that we always get a value of at least 11 (the lowest the current month can be is 1). In php programming % means that we get the Modulus or Remainder of the first number divided by the last number. We then add 1 to the number so that we can always have the previous month whether is be January or December. Here is one more example that might help you understand better. Should the $current_month have a value of 1 the following math would be used:

(1 + 10) = 11
11%12 = 11
11 + 1 = 12 (meaning that the previous month would be december).

This allows us to find the previous month even if its in a previous year without the use of conditional statements. Now lets look at the basic setup of our calendar.


echo '

';
echo '

';
for ($week=0; $week<6; $week++) { echo '

';
for ($day=0; $day<7; $day++) { $date = ($day + $week*7 + $offset)%$num_days_in_month + 1; if ($date == 1) { $num_days_in_month = $num_days_in_this_month; $offset = $num_days_in_month - $index_of_last_day_of_last_month - 1; $curr_month++; $curr_year += ($curr_month > 12);
}
echo '

';
}
echo '

';
}
echo '

Su M T W Th F S
'.$date.'

';

When I first started designing this calendar, I was so afraid of using a table. I was afraid that it was bad design to use a table, but then my friend Joseph gave me a little advise: If its tabular data use a table to store it in. I personally can’t think of anything more tabular than a calendar. As you can see from above we start with table headings that show the names of each of the 7 days of the week (Sunday – Saturday). We also could have used a loop for those but it makes more sense and uses less code to do it the old fashioned way. After we have our table heading we will start by looping through each of the weeks (as stated earlier we will use 6 as our number regardless of what month we are in). In my opinion using 6 weeks make the calendar uniform for all months. Within each of our month loops we’ll loop through 7 days of the week (Sunday – Saturday) regardless of what month they fall in. We’ll also use a few simple conditions to see if we should increase our month. At the most we will be dealing with 3 consecutive months (Last Month, Current Month, and Next Month). After we’ve got this basic structure down we can create a calendar as big or as small as we’d like using the help of CSS. We can also format certain days, weeks, or even different months anyway we want.


Leave a Reply

Your email address will not be published.