CALENDAR TIME DATE PHP

Sometimes telling what day it is can be a task for even the smartest of people. Therefore, we can create cool stuff in PHP such as calendars and stick them on our websites to show off your mad coding skills as a PHP developer. In this tutorial, we’re going to create a calendar using PHP. There may be simpler ways of creating a calendar than the examples in this tutorial, but that’s ok because we’re going to practice using some advanced arrays, date/time functions and work on utilizing some other features of PHP that you may not be familiar with.

Grab yourself a cup of coffee, soda, smoke or whatever your pleasure is because this tutorial could make your head hurt, I know my head hurt when coming up with this code!

Before we begin tearing into this calendar, I want you to understand that we are not making this object oriented by creating a function or a class for it. The reason is I want this to tutorial to be as basic as possible, plus it will allow room for a follow-on tutorial that I have planned to show you how to utilize this calendar to it’s full potential.

Also, you may want to view the screen shot below in Figure 1.1 to understand what the calendar will look like. Additionally, you can click on this hyperlink to view the calendar in action.


Figure 1.1: Calendar

Planning and Concept

Planning a calendar shouldn’t be too hard right? Well, have you thought about all of the variables involved in creating a calendar that will do exactly what we need? A true calendar can be a PHP developers’ logic nightmare. The calendar that I came up with uses an HTML table that has seven columns across and starts with Sunday in the first column and ends on Saturday on the right column. Then I had to make it dynamic enough to figure out how many weeks are in the month. Sometimes days start at the
end(array array_arg)

Advances array argument’s internal pointer to the last element and return it’, CAPTION, ‘end’);”>end of the week and could create a problem for you to create another row in your table.

It’s fairly easy to figure out how many days are in the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current month by using PHP, but how about How many days are in the last month? That’s pretty easy to do also, however what method would we use to merge those two values together to fit the HTML table properly? Also, what if we want to shade the days that are outside of the month? Well, this tutorial will show you how to figure all of that out.

There’s more concepts than I care to try to explain up front, so we’ll break things down in this tutorial in depth.

PHP Configuration

This calendar requires a special option to be enabled when you configure PHP. The option flags on Linux are: –enable-calendar in your configuration directives. In Windows, I believe you do not have to do anything special if you installed from the PHP Installer found at php.net/downloads.php

Additionally, we are going to be turning error_reporting and display_errors off in the actual code of this script. Is this good habbit? Sure. As long as it functions properly, then you don’t need to see every little error and warning that PHP encounters, so we’ll be fine. Besides, on a production server, I highly recommend shutting error_reporting AND display_errors completely off. If you need to debug something, you’ll know when to turn it back on.

Let’s jump to the
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next page and view some code!

 

In this tutorial, I’m going to show you the entire code broken down into pieces first. If you are a codeshark and don’t care about how it works, then you can just skip to page 5 and grab the code, however I really recommend you read this tutorial to understand the logic behind the way I developed this calendar. You may even learn something, I know I sure did! Let’s begin by setting up some standard HTML for this file. We’ll be assigning styles to different elements of the calendar, so I decided to create some styles for it below.

PHP Example: (!)


<html>
<
head>
<
title>PHP Calendar</title>
<
style type="text/css">
<!--

The first style is the table outline of the calendar. I used a collapse method of the border as shown here.

PHP Example: (!)


.table.calendar {border1px solid #000000; border-collapse: collapse; color: #000000; background: #FFFFFF; }

The
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next style is for the table cell of the selected date. For example, if we selected July 18th, then the cell with the
date(string format [, int timestamp])

Format a local time/date’, CAPTION, ‘date’);”>date of “18” would be shaded.

PHP Example: (!)

.td.today border1px solid whitecolor#000000; background: #EFEFEF; font-weight: bold;}

The
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next style is used for days within the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current month. It’s a basic style with a 1 pixel border and the background is white.

PHP Example: (!)

.td.monthdays {border1px solid #434470; color: #000000; background: #FFFFFF;}

The last style is “nonmonthdays” for days that are displayed in the calendar but fall outside of the selected month that is displayed.

PHP Example: (!)

.td.nonmonthdays border1px solid whitecolor#000000; background: #EFEFEF;}
-->
</
style>
<
body>

Let’s jump into the PHP code. I started PHP with the open tag and then set the
error_reporting(int new_error_level=null)

Return the current error_reporting level, and if an argument was passed – change to the new level’, CAPTION, ‘error_reporting’);”>error_reporting level to 0. This ensures that no errors will be reported or displayed to the browser.

PHP Example: (!)

<?php
error_reporting
('0');
ini_set('display_errors''0');

Next, we are going to determine which arguments have been passed to the script by the querystring value of date. Example: cal.php?date=XXXXXXXXXX where XXXXXXX is the timestamp of the day and month we wish to view. If no
date(string format [, int timestamp])

Format a local time/date’, CAPTION, ‘date’);”>date argument has been passed to the script, we will set the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current
date(string format [, int timestamp])

Format a local time/date’, CAPTION, ‘date’);”>date to today. We determine this method by using the isset() by checking if an error is returned from the Boolean. If no
date(string format [, int timestamp])

Format a local time/date’, CAPTION, ‘date’);”>date argument is passed, then we’ll set one.

PHP Example: (!)


// Gather variables from
// user input and break them
// down for usage in our script

if(!isset($_REQUEST['date'])){

If no
date(string format [, int timestamp])

Format a local time/date’, CAPTION, ‘date’);”>date argument is passed, then we’ll set one by using the mktime() function for the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current month,
date(string format [, int timestamp])

Format a local time/date’, CAPTION, ‘date’);”>date and year.

PHP Example: (!)


   $date 
mktime(0,0,0,date('m'), date('d'), date('Y'));
} else {

In the ELSE portion of this statement, we have determined that the
date(string format [, int timestamp])

Format a local time/date’, CAPTION, ‘date’);”>date argument was set, so therefore we’ll use the
date(string format [, int timestamp])

Format a local time/date’, CAPTION, ‘date’);”>date passed to the script.

PHP Example: (!)


   $date 
$_REQUEST['date'];
}

Note: the previous example regarding the
date(string format [, int timestamp])

Format a local time/date’, CAPTION, ‘date’);”>date argument could have been reversed, depending on your preference. I don’t like typing some code over and over again, especially functions. In this script, we’re going to be using the $day, $month, $year values that we set here by using the date() function.

PHP Example: (!)


$day 
date('d'$date);
$month date('m'$date);
$year date('Y'$date);

Alright, now we are going to dig into figuring out exactly how to determine the best method of finding information about the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current month we are viewing. We start by setting variable named $month_start which is a timestamp of the very first second of the very first day for the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current month and year being displayed. We’ll use this variable later when we need it, for now, I am just setting up my script with easy variables to use later on.

PHP Example: (!)


// Get the first day of the month
$month_start mktime(0,0,0,$month1$year);

At the top of our table, we are going to be displaying the abbreviated month name, so I grab this and turn it into a variable by using the date() function again with the ‘M’ descriptor.

PHP Example: (!)


// Get friendly month name
$month_name date('M'$month_start);

Here’s where things start to get tricky. We need to figure out what day of the week the first of the month is. So, we can use
date(string format [, int timestamp])

Format a local time/date’, CAPTION, ‘date’);”>date function once again by using that $month_start variable we created earlier. The output of this would be “Sun, Mon, Tue….” And so on.

PHP Example: (!)


// Figure out which day of the week
// the month starts on.
$month_start_day date('D'$month_start);

Now that we have determined which day of the week the month starts on, we are going to create a number I call “offset” based on the values returned by the $month_start value. The output of this script would be a number. For example, if the month starts on a Sunday, the offset will be ‘0’ and this we now know that we don’t have to determine how many days from the previous month to enter into the table. On another note, if the start of the month is a Wednesday, we’ll need to set an offset of ‘3’ and then we’ll utilize 3 days from the previous month to make our HTML table line up properly. Confused? If so, keep reading, this should make more sense later when we use the $offset value.

PHP Example: (!)


switch($month_start_day){
    case 
"Sun"$offset 0; break;
    case 
"Mon"$offset 1; break;
    case 
"Tue"$offset 2; break;
    case 
"Wed"$offset 3; break;
    case 
"Thu"$offset 4; break;
    case 
"Fri"$offset 5; break;
    case 
"Sat"$offset 6; break;
}

We now know how many columns we need to move the first of the month over by the $offset value. But wait! How many days were in the month before this one? Were there 28, 29, 30 or 31? How will we fill in the cells before the first of the month with the appropriate values? Here, we’ll use the PHP calendar functions to determine that. Uh oh! Wait a second? Have you thought about if the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current month was January 2002? How would we get the number of days for December of 2001? Well, we use an IF statement to check if the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current month is set to ‘1’ indicating that we are on January. If it is, then we’ll utilize a separate set of instructions for the cal_days_in_month function.

PHP Example: (!)


// determine how many days are in the last month.
if($month == 1){
   
$num_days_last cal_days_in_month(012, ($year -1));
} else {
   
$num_days_last cal_days_in_month(0, ($month -1), $year);
}

Ok, now that we have determined the proper number of days for the last month, regardless of which month we are currently in, we can now grab the number of days for this month. There are no special rules we need to follow here, so we’ll just use the standard cal_days_in_month function with the $month and $year variables we created earlier.

PHP Example: (!)


// determine how many days are in the current month.
$num_days_current cal_days_in_month(0$month$year);

Now that we have the days of this month and the previous month figured out, we’ll jump into some building some arrays to work with. We’ll build our arrays using the for loop on the $num_days_current variable and increment the $i value
each(array arr)

Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element’, CAPTION, ‘each’);”>each
time(void)

Return current UNIX timestamp’, CAPTION, ‘time’);”>time the loop is passed until we have created an array element for
each(array arr)

Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element’, CAPTION, ‘each’);”>each day in the month.

PHP Example: (!)


// Build an array for the current days
// in the month
for($i 1$i <= $num_days_current$i++){
    
$num_days_array[] = $i;
}

The
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next code portion is the same as the previous one, except we are going to create a new array for the number of days for the last month.

PHP Example: (!)


// Build an array for the number of days
// in last month
for($i 1$i <= $num_days_last$i++){
    
$num_days_last_array[] = $i;
}

At this point, we have two arrays. The $num_days_array is an array of the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current days in this month and the $num_days_last_array is an array of the number of days for last month. It’s
time(void)

Return current UNIX timestamp’, CAPTION, ‘time’);”>time to slice and merge the appropriate values together to make the beginning of our calendar. To better understand what we are trying to do, take this into consideration. Let’s say last month had 30 days and this month starts on a Wednesday. The first portion of our calendar starting with Sunday of the first week would look like this: 28, 29, 30, 1 (Wednesday). After we create the array to work with, we’ll have no problems creating the first 90% of our calendar HTML.

PHP Example: (!)


// If the $offset from the starting day of the
// week happens to be Sunday, $offset would be 0,
// so don't need an offset correction.

if($offset 0){

Remember that $offset value we created earlier? Well, if it is greater than ‘0’, meaning that the month start
date(string format [, int timestamp])

Format a local time/date’, CAPTION, ‘date’);”>date is any day besides Sunday, we’ll need to create a special array from the values.

We achieve this by using the array_slice function which will slice an array by from a certain position for the number of elements
defined(string constant_name)

Check whether a constant exists’, CAPTION, ‘defined’);”>defined in the arguments of this function. In our case, we are going to create an temporary array with the last portion of the previous month to fill in the offset value with the correct days. So, we slice the $num_days_last_array array starting from the
end(array array_arg)

Advances array argument’s internal pointer to the last element and return it’, CAPTION, ‘end’);”>end of the array and counting backwards the number of elements we need to grab by uinsg a negative value of the $offset value and we will also set the length of the slice to the number of $offset. In simple terms, if our $offset was ‘3’, we are going to create a new value from the last 3 elements of the array.

PHP Example: (!)


    $offset_correction 
array_slice($num_days_last_array, -$offset$offset);

Now that we have our $offset_correction array which contains the days from last month we need, we’ll create a new array by merging the $offset_correction (last months’ days we need) and the $num_days_array (days for this month) together using array_merge. Now we have the lead in for the month plus all of the days in the month in an array! Whew, that was painful huh?

PHP Example: (!)


    $new_count 
array_merge($offset_correction$num_days_array);

Now, we want to figure out how many days we currently have in the offset, so we can use the
count(mixed var [, int mode])

Count the number of elements in a variable (usually an array)’, CAPTION, ‘count’);”>count function to
count(mixed var [, int mode])

Count the number of elements in a variable (usually an array)’, CAPTION, ‘count’);”>count the array elements for $offset_correction. We’ll use this variable later on as well.

PHP Example: (!)


    $offset_count 
count($offset_correction);
}

// The else statement is to prevent building the $offset array.
else {

If by chance the first of the month was a Sunday, we need to skip all of the offset corrections we were doing in the previous steps. We still need the $new_count later on in this script, so we’ll just assign the $num_days_array to $new_count and press on with it!

PHP Example: (!)


    $new_count 
$num_days_array;
}

Our
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next task is to create a variable by counting the array elements in the $new_count array that we created previously. We’ll be using this number again later as well.

PHP Example: (!)


// count how many days we have with the two
// previous arrays merged together
$current_num count($new_count);

Let’s do a quick recap of what we have covered so far. We had to determine the month, day and year that we are going to display. If no input was found, then we set it to the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current date. Next, we had to figure out how many days are in this month and what day of the week this month starts on. Based on the findings thus far, we need to build an offset value and determine how many days were in last month, then we start counting backwards to fill in the beginning of the week from the days of last month with the appropriate values.

At this point, we have built an array with the days from last month and the days from this month all merged together in the proper order. On the
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next page, we’re going to work on how to setup our HTML calendar properly for what we have found out so far.

Now that we have all of our calculations figured out, we are ready to start determining some more values that will help us build our HTML table properly. We start off by figuring out exactly how many rows we are going to need to display this calendar like it should be displayed.

PHP Example: (!)


// Since we will have 5 HTML table rows (TR)
// with 7 table data entries (TD)
// we need to fill in 35 TDs
// so, we will have to figure out
// how many days to appened to the end
// of the final array to make it 35 days.

If the $current_num is greater than 35 (7 days * 4 weeks), we will set the number of weeks to 6. This is how many table rows we are going to draw in this situation.

PHP Example: (!)


if($current_num 35){
   
$num_weeks 6;

At this point, we’re going to create another variable called $outset. Let’s say that our month ends on a Tuesday, well, we need to fill in the rest of the table with
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next months’ starting dates right? Yep. So, at this point, we know we are going to be drawing 42 table cells in our calendar to represent the days. So, our outset must be 42 minus the number of days we have already and then we’ll have a number to work with later on.

PHP Example: (!)


   $outset 
= (42 $current_num);
} elseif(
$current_num 35){

If the $current_num is less than 35, we will draw 5 rows (5 weeks) in the table

PHP Example: (!)


   $num_weeks 
5;
   
$outset = (35 $current_num);
}

In the event that we happen to have exactly 35 days, we need to set the number of weeks to ‘5’ and set the $outset variable to ‘0’. This prevents our loops that we will use later on from displaying incorrect information.

PHP Example: (!)


if($current_num == 35){
   
$num_weeks 5;
   
$outset 0;
}

Ok, at this point, we now know what our $outset value is, so therefore, we are going to append the keys to our $new_count array to fill in the rest of the values for the last week of the month with the number of days we need to display for
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next month. For example, if our month had 30 days and it ended on Thursday, we need to fill in the days for this last table row of our calendar with the days of
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next month until Saturday. After this
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next bit of code, the
end(array array_arg)

Advances array argument’s internal pointer to the last element and return it’, CAPTION, ‘end’);”>end of our $new_count array would be something like: 30, 1, 2.

PHP Example: (!)


// Outset Correction
for($i 1$i <= $outset$i++){
   
$new_count[] = $i;
}

We’re getting there! Now, we are going to use a function called array_chunk which allows you to break a
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current array into sub arrays with chunks of the original array. Whew! Basically, we are going to create sub arrays for every 7 days to represent weeks.

PHP Example: (!)


// Now let's "chunk" the $new_count array
// into weeks. Each week has 7 days
// so we will array_chunk it into 7 days.
$weeks array_chunk($new_count7);

Here’s a quick recap for this page. At this point, we should have an array named $weeks that has either 35 or 42. This number is obtained from the number of days in a week (7) multiplied by the number of weeks we have in this month. This array is also broken down into a sub array with the days of
each(array arr)

Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element’, CAPTION, ‘each’);”>each week in their respective sub arrays. If you were to print_r($weeks) on this array, you should get a clear picture of what I am talking about.

On the
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next page, we’re going to start actually drawing the calendar. If you are confused now, wait until the
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next page, you may be confused even more because this gets a little more complicated.

Alright, we now have the correct number of weeks and days to fill
each(array arr)

Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element’, CAPTION, ‘each’);”>each block of those weeks from the previous month, the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current month and the
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next month. Now it’s
time(void)

Return current UNIX timestamp’, CAPTION, ‘time’);”>time to start working on our calendar layout some more.

We’ll start off by creating two variables: $previous_link which takes the user to the previous month calendar and then $next_link which naturally displays
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next month’s calendar.

Remember earlier when I mentioned about viewing January and going to the previous month? Well, we have to create a special
link(string target, string link)

Create a hard link’, CAPTION, ‘link’);”>link for the Previous
link(string target, string link)

Create a hard link’, CAPTION, ‘link’);”>link when viewing January and also one for viewing December to go to the
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next year and month.

Before I get criticized, I know that
mktime(int hour, int min, int sec, int mon, int day, int year)

Get UNIX timestamp for a date’, CAPTION, ‘mktime’);”>mktime allows you to use numbers like 13 as the month and it will go to January of the
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next year, however I prefer to keep things lined up properly and in turn, I create a
link(string target, string link)

Create a hard link’, CAPTION, ‘link’);”>link using
mktime(int hour, int min, int sec, int mon, int day, int year)

Get UNIX timestamp for a date’, CAPTION, ‘mktime’);”>mktime with the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current year values. The links below utilize the $_SERVER[‘PHP_SELF’] superglobal to display the URL as the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current script being executed and we also create a timestamp for the appropriate month and
date(string format [, int timestamp])

Format a local time/date’, CAPTION, ‘date’);”>date clicked on by the user.

PHP Example: (!)


$previous_link 
"<a href="".$_SERVER['PHP_SELF']."?date=";
if(
$month == 1){
   
$previous_link .= mktime(0,0,0,12,$day,($year -1));
} else {
   
$previous_link .= mktime(0,0,0,($month -1),$day,$year);
}
$previous_link .= ""><< Prev</a>";

$next_link "<a href="".$_SERVER['PHP_SELF']."?date=";
if(
$month == 12){
   
$next_link .= mktime(0,0,0,1,$day,($year 1));
} else {
   
$next_link .= mktime(0,0,0,($month +1),$day,$year);
}
$next_link .= "">Next >></a>";

At this point, we are going to build our calendar table and setup the first two rows. The first row will display the Previous and
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘Next’);”>Next links with the abbreviated month name and year inside of an imbedded table. I used an imbedded table for alignment purposes.

PHP Example: (!)


  
// Build the heading portion of the calendar table
echo "<table border="1" cellpadding="2" cellspacing="0" width="300" class="calendar">n".
     
"<tr>n".
     
"<td colspan="7">".
     
"<table align="center">".
     
"<tr>".
     
"<td colspan="2" width="75" align="left">$previous_link</td>n".
     
"<td colspan="3" width="150" align="center">$month_name $year</td>n".
     
"<td colspan="2" width="75" align="right">$next_link</td>n".
     
"</tr>n".
     
"</table>n".
     
"</td>n".
     
"<tr>n".

The
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next row indicates which day of the week
each(array arr)

Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element’, CAPTION, ‘each’);”>each column is for.

PHP Example: (!)


"<td>S</td><td>M</td><td>T</td><td>W</td><td>T</td><td>F</td><td>S</td>n".
     
"</tr>n";

Now it’s
time(void)

Return current UNIX timestamp’, CAPTION, ‘time’);”>time to really dig in and display the calendar. What makes this code so difficult is the fact that we need to know when to shade a cell that does not belong to the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current month with the appropriate style we setup in the styles of this HTML document.

Additionally we are going to determine which day of the month is selected (or today by default) and shade it accordingly.

PHP Example: (!)


// Now we break each key of the array 
// into a week and create a new table row for each
// week with the days of that week in the table data

We need a way to track which loop cycle we are currently using, so we will set a variable named $i with the initial value of 0. This value is outside of the for loops and will be incremented as we loop through the arrays.

PHP Example: (!)


$i 
0;

The
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next task is to loop through
each(array arr)

Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element’, CAPTION, ‘each’);”>each of the weeks sub arrays in our $weeks array. When we do this, we want to make
each(array arr)

Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element’, CAPTION, ‘each’);”>each sub array in the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current loop cycle a new array called $week which we will use in the
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next loop cycle.

PHP Example: (!)


foreach($weeks AS $week){

We now know that we are inside of a week, so we’ll draw the table row (<tr>) for this week and begin draw.

PHP Example: (!)


       
echo "<tr>n";

The
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next loop cycle will draw the table cell for the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current day in the loops. We do this by looping
each(array arr)

Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element’, CAPTION, ‘each’);”>each of the sub arrays we built earlier and breaking it down as a single variable named $d (for day).

PHP Example: (!)


       
foreach($week as $d){

Now it’s
time(void)

Return current UNIX timestamp’, CAPTION, ‘time’);”>time to get on with the really tricky stuff! We will use some advanced arguments in the IF statements below to determine how to properly shade the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current day we are looping.

To start off, if the $i value is less than the $offset_count we know that this is a day from the previous month, so we will draw the table, insert the value of the array element being looped ($d) and apply the appropriate CSS style to it. While we are at it, we’ll create a hyperlink to allow someone to select this day.

PHP Example: (!)


         
if($i $offset_count){
             
$day_link "<a href="".$_SERVER['PHP_SELF']."?date=".mktime(0,0,0,$month -1,$d,$year)."">$d</a>";
             echo 
"<td class="nonmonthdays">$day_link</td>n";
         }

If the previous IF statement was not TRUE on the result, then nothing would have been drawn yet, so we are going to check and determine if the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current day being looped belongs to the month being displayed. At the same time, we need to ensure that it 1.) does not belong to the previous month and 2.) does not belong to the
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next month. If both of these rules are passed, then the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current day must fall into the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current month being displayed.

PHP Example: (!)


         
if(($i >= $offset_count) && ($i < ($num_weeks 7) - $outset)){

Alright, here’s a catchy part. We will determine if the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current day of the $date value (argument passed to the script, or set if no
date(string format [, int timestamp])

Format a local time/date’, CAPTION, ‘date’);”>date argument is passed) is the same as the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current day being looped for this cycle, if it is, we will not display a hyperlink and we will shade the day with the appropriate CSS style.

PHP Example: (!)


           
if($date == mktime(0,0,0,$month,$d,$year)){
               echo 
"<td class="today">$d</td>n";
           } else {

At this point, we know that the day in the loop cycle is not the selected day of the $date argument passed to the script, so we’ll draw a hyperlink and allow our users to click on that day to select it.

PHP Example: (!)


               
echo "<td class="days"><a href="".$_SERVER['PHP_SELF']."?date=".mktime(0,0,0,$month,$d,$year)."">$d</a></td>n";
           }

        } elseif($i >= ($num_weeks 7) - $outset) {

At this point, if all of the rules we have set previously have not drawn a cell yet, we are going to check and make sure that the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current
date(string format [, int timestamp])

Format a local time/date’, CAPTION, ‘date’);”>date belongs to the
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next month (offset) if it does, we’ll draw the leadout cells to fill in the dates of
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next month from the
end(array array_arg)

Advances array argument’s internal pointer to the last element and return it’, CAPTION, ‘end’);”>end of the
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current month to Saturday of the last week. We will also create the hyperlinks and shade them appropriately with the CSS style we desire.

PHP Example: (!)


            $day_link 
"<a href="".$_SERVER['PHP_SELF']."?date=".mktime(0,0,0,$month +1,$d,$year)."">$d</a>";
            echo 
"<td class="nonmonthdays">$day_link</td>n";
        }

Remember that good ol’ $i value? Well, it’s
time(void)

Return current UNIX timestamp’, CAPTION, ‘time’);”>time to increment it by 1 for the
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next day in our loop so that the all of the IF statements we coded will work properly.

PHP Example: (!)

  $i++;

Close out the for loop for $week AS $d.

PHP Example: (!)


      
}

Close out the table row for this
current(array array_arg)

Return the element currently pointed to by the internal array pointer’, CAPTION, ‘current’);”>current week.

PHP Example: (!)


      
echo "</tr>n";   
}

Now close out your calendar table, PHP and your HTML tags and you’re all done!

PHP Example: (!)


// Close out your table and that's it!
echo '<tr><td colspan="7" class="days"> </td></tr>';
echo 
'</table>';
?>
</body>
</html>

Whew! Did you get all of that? Let’s check out the full code flow on the
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next page.

PHP Calendar Full Code

PHP Example: (!)


<html>
<
head>
<
title>PHP Calendar</title>
<
style type="text/css">
<!--
.
table.calendar {border1px solid #000000; border-collapse: collapse; color: #000000; background: #FFFFFF; }
.td.today border1px solid whitecolor#000000; background: #EFEFEF; font-weight: bold;}
.td.monthdays {border1px solid #434470; color: #000000; background: #FFFFFFF; }
.td.nonmonthdays border1px solid whitecolor#000000; background: #EFEFEF;}
-->
</
style>
<
body>

<?php
error_reporting
('0');
ini_set('display_errors''0');
// Gather variables from
// user input and break them
// down for usage in our script

if(!isset($_REQUEST['date'])){
   
$date mktime(0,0,0,date('m'), date('d'), date('Y'));
} else {
   
$date $_REQUEST['date'];
}

$day date('d'$date);
$month date('m'$date);
$year date('Y'$date);

// Get the first day of the month
$month_start mktime(0,0,0,$month1$year);

// Get friendly month name
$month_name date('M'$month_start);

// Figure out which day of the week
// the month starts on.
$month_start_day date('D'$month_start);

switch($month_start_day){
    case 
"Sun"$offset 0; break;
    case 
"Mon"$offset 1; break;
    case 
"Tue"$offset 2; break;
    case 
"Wed"$offset 3; break;
    case 
"Thu"$offset 4; break;
    case 
"Fri"$offset 5; break;
    case 
"Sat"$offset 6; break;
}

// determine how many days are in the last month.
if($month == 1){
   
$num_days_last cal_days_in_month(012, ($year -1));
} else {
   
$num_days_last cal_days_in_month(0, ($month -1), $year);
}
// determine how many days are in the current month.
$num_days_current cal_days_in_month(0$month$year);

// Build an array for the current days
// in the month
for($i 1$i <= $num_days_current$i++){
    
$num_days_array[] = $i;
}

// Build an array for the number of days
// in last month
for($i 1$i <= $num_days_last$i++){
    
$num_days_last_array[] = $i;
}

// If the $offset from the starting day of the
// week happens to be Sunday, $offset would be 0,
// so don't need an offset correction.

if($offset 0){
    
$offset_correction array_slice($num_days_last_array, -$offset$offset);
    
$new_count array_merge($offset_correction$num_days_array);
    
$offset_count count($offset_correction);
}

// The else statement is to prevent building the $offset array.
else {
    
$offset_count 0;
    
$new_count $num_days_array;
}

// count how many days we have with the two
// previous arrays merged together
$current_num count($new_count);

// Since we will have 5 HTML table rows (TR)
// with 7 table data entries (TD)
// we need to fill in 35 TDs
// so, we will have to figure out
// how many days to appened to the end
// of the final array to make it 35 days.

if($current_num 35){
   
$num_weeks 6;
   
$outset = (42 $current_num);
} elseif(
$current_num 35){
   
$num_weeks 5;
   
$outset = (35 $current_num);
}
if(
$current_num == 35){
   
$num_weeks 5;
   
$outset 0;
}
// Outset Correction
for($i 1$i <= $outset$i++){
   
$new_count[] = $i;
}

// Now let's "chunk" the $all_days array
// into weeks. Each week has 7 days
// so we will array_chunk it into 7 days.
$weeks array_chunk($new_count7);

// Build Previous and Next Links
$previous_link "<a href="".$_SERVER['PHP_SELF']."?date=";
if(
$month == 1){
   
$previous_link .= mktime(0,0,0,12,$day,($year -1));
} else {
   
$previous_link .= mktime(0,0,0,($month -1),$day,$year);
}
$previous_link .= ""><< Prev</a>";

$next_link "<a href="".$_SERVER['PHP_SELF']."?date=";
if(
$month == 12){
   
$next_link .= mktime(0,0,0,1,$day,($year 1));
} else {
   
$next_link .= mktime(0,0,0,($month +1),$day,$year);
}
$next_link .= "">Next >></a>";

// Build the heading portion of the calendar table
echo "<table border="1" cellpadding="2" cellspacing="0" width="300" class="calendar">n".
     
"<tr>n".
     
"<td colspan="7">n".
     
"<table align="center">n".
     
"<tr>n".
     
"<td colspan="2" width="75" align="left">$previous_link</td>n".
     
"<td colspan="3" width="150" align="center">$month_name $year</td>n".
     
"<td colspan="2" width="75" align="right">$next_link</td>n".
     
"</tr>n".
     
"</table>n".
     
"</td>n".
     
"<tr>n".
     
"<td>S</td><td>M</td><td>T</td><td>W</td><td>T</td><td>F</td><td>S</td>n".
     
"</tr>n";

// Now we break each key of the array 
// into a week and create a new table row for each
// week with the days of that week in the table data

$i 0;
foreach(
$weeks AS $week){
       echo 
"<tr>n";
       foreach(
$week as $d){
         if(
$i $offset_count){
             
$day_link "<a href="".$_SERVER['PHP_SELF']."?date=".mktime(0,0,0,$month -1,$d,$year)."">$d</a>";
             echo 
"<td class="nonmonthdays">$day_link</td>n";
         }
         if((
$i >= $offset_count) && ($i < ($num_weeks 7) - $outset)){
            
$day_link "<a href="".$_SERVER['PHP_SELF']."?date=".mktime(0,0,0,$month,$d,$year)."">$d</a>";
           if(
$date == mktime(0,0,0,$month,$d,$year)){
               echo 
"<td class="today">$d</td>n";
           } else {
               echo 
"<td class="days">$day_link</td>n";
           }
        } elseif((
$outset 0)) {
            if((
$i >= ($num_weeks 7) - $outset)){
               
$day_link "<a href="".$_SERVER['PHP_SELF']."?date=".mktime(0,0,0,$month +1,$d,$year)."">$d</a>";
               echo 
"<td class="nonmonthdays">$day_link</td>n";
           }
        }
        
$i++;
      }
      echo 
"</tr>n";   
}

// Close out your table and that's it!
echo '<tr><td colspan="7" class="days"> </td></tr>';
echo 
'</table>';
?>
</body>
</html>

Let’s summarize on the
next(array array_arg)

Move array argument’s internal pointer to the next element and return it’, CAPTION, ‘next’);”>next page.

Leave a comment