Separate date calculations from the HTML output so the calendar logic is easier to maintain.
$month = new DateTimeImmutable('2026-09-01');
$days = (int) $month->format('t');
$firstWeekday = (int) $month->format('w');
echo $days . ' days, starts on weekday ' . $firstWeekday;$start_year=(int)date('Y')-10; // Starting year for dropdown list box
$end_year=(int)date('Y')+10; // Ending year for dropdown list box
We have two JavaScript functions inside our script. One is used to pass the selected date value from calendar window to main calling page. Other one is used to reload the page by taking selected value from month and year dropdown list box.
Function post_value() receives three parameters , month ,date and year from the calendar cell and posted the same value to parent window. You can read more on passing value to parent window here.
function post_value(mm,dt,yy){
opener.document.f1.p_name.value = mm + "/" + dt + "/" + yy;
/// cheange the above line for different date format
self.close();
}
Function reload(form) collects month and year value from the dropdown list box and using that it prepare the query string. With the query string the page is reloaded.
function reload(form){
var month_val=document.getElementById('month').value; // collect month value
var year_val=document.getElementById('year').value; // collect year value
self.location='cal2.php?month=' + month_val + '&year=' + year_val ; // reload the page
}
There is a style associated with the page, you can change the style to change the display style of calendar.
$_GET values.
$month = filter_input(INPUT_GET, 'month', FILTER_VALIDATE_INT);
$year = filter_input(INPUT_GET, 'year', FILTER_VALIDATE_INT);
The calendar needs valid month and year values. If either value is missing or outside the allowed range, use the current month or year as the default.
if ($month === false || $month < 1 || $month > 12) {
$month = (int) date('n');
}
if ($year === false || $year < $start_year || $year > $end_year) {
$year = (int) date('Y');
}
After getting date about year and month we have to find out the number of days present in the month. There is a built in function cal_days_in_month available to get this.
$no_of_days = cal_days_in_month(CAL_GREGORIAN, $month, $year);//calculate number of days in a month
$j= date('w',mktime(0,0,0,$month,1,$year)); // This will calculate the week day of the first day of the month
$j= date('w',mktime(0,0,0,$month,1,$year)); // This will calculate the week day of the first day of the month
//echo $j;// Sunday=0 , Saturday =6
//// if starting day of the week is Monday then add following two lines ///
$j=$j-1;
if($j<0){$j=6;} // if it is Sunday //
//// end of if starting day of the week is Monday ////
In addition to this Top row of the table to be changed to display week day name starting from Monday and ending on Sunday.
//echo "<tr><th>Sun</th><th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th>Sat</th></tr><tr>";
echo "<tr><th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th>Sat</th><th>Sun</th></tr><tr>";
Inside your zip file ( download at the end of this page ) cal3.php file is included which shows calendar where week starts from Monday
$adj=str_repeat("<td bgcolor='#ffff00'>* </td>",$j); // Blank starting cells of the calendar
$blank_at_end=42-$j-$no_of_days; // Days left after the last day of the month
if($blank_at_end >= 7){$blank_at_end = $blank_at_end - 7 ;}
$adj2=str_repeat("<td bgcolor='#ffff00'>* </td>",$blank_at_end); // Blank ending cells of the calendar
Here the number 42 ( 7 x 6 ) is the maximum number of cells of the calendar full filling any year - months requirement.
<select name=month value='' onchange="reload(this.form)" id="month">
<option value=''>Select Month</option>";
for($p=1;$p<=12;$p++){
$dateObject = DateTime::createFromFormat('!m', $p);
$monthName = $dateObject->format('F');
if($month==$p){
echo "<option value=$p selected>$monthName</option>";
}else{
echo "<option value=$p>$monthName</option>";
}
}
echo "</select>
In the above code we used createFromFormat function to create date object.
<select name=year value='' onchange="reload(this.form)" id="year">Select Year</option>
";
for($i=$start_year;$i<=$end_year;$i++){
if($year==$i){
echo "<option value='$i' selected>$i</option>";
}else{
echo "<option value='$i'>$i</option>";
}
}
echo "</select>
Both our dropdown lists will use onChange event handler to trigger JavaScript function reload() to refresh the page when ever user changes its selection of month or year.
echo " </td><td align='center'><a href=# onClick='self.close();'>X</a></td></tr><tr>";
echo "<th>Sun</th><th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th>Sat</th></tr><tr>";
To display the numbers ( date ) in the calendar cell we will use one for loop. The loop will start from 1 and continue till total number of days present in a month ( variable $no_of_days )
for($i=1;$i<=$no_of_days;$i++){
$onclick = sprintf('post_value(%d,%d,%d); return false;', $month, $i, $year);
echo $adj . '<td><a href="#" onclick="' . htmlspecialchars($onclick, ENT_QUOTES, 'UTF-8') . '">' . $i . '</a>'; // Display the date inside the calendar cell
echo " </td>";
$adj='';
$j ++;
if($j==7){echo "</tr><tr>"; // start a new row
$j=0;}
}
Inside the for loop we will add hyper link to each number ( day ) of the calendar to carry the month , date and year to parent window by using JavaScript function post_value();
$onclick = sprintf('post_value(%d,%d,%d); return false;', $month, $i, $year);
echo $adj . '<td><a href="#" onclick="' . htmlspecialchars($onclick, ENT_QUOTES, 'UTF-8') . '">' . $i . '</a>'; // Display the date inside the calendar cell
Before starting of this loop will display the data stored in $adj to block the blank cells before 1st day of the month. Similarly we will display $adj2 which stores the blank cells after the last date of the month.
cal2.php and cal3.php demos validate month/year inputs; apply the same validation whenever query-string values control the calendar. You can download the zip file at the end.
<?php
//// Settings, change this to match your requirment //////
$start_year=2015; // Starting year for dropdown list box
$end_year=2030; // Ending year for dropdown list box
////// end of settings ///////////
?>
<!doctype html public "-//w3c//dtd html 3.2//en">
<html>
<head>
<title>plus2net Calendar</title>
<link rel="canonical" href="https://www.plus2net.com/php_tutorial/cal2.php"/>
<script langauge="javascript">
function post_value(mm,dt,yy){
opener.document.f1.p_name.value = mm + "/" + dt + "/" + yy;
/// cheange the above line for different date format
self.close();
}
function reload(form){
var month_val=document.getElementById('month').value; // collect month value
var year_val=document.getElementById('year').value; // collect year value
self.location='cal2.php?month=' + month_val + '&year=' + year_val ; // reload the page
}
</script>
<style type="text/css">
table.main {
width: 100%;
border: 1px solid black;
background-color: #9dffff;
}
table.main td {
font-family: verdana,arial, helvetica, sans-serif;
font-size: 11px;
}
table.main th {
border-width: 1px 1px 1px 1px;
padding: 0px 0px 0px 0px;
background-color: #ccb4cd;
}
table.main a{TEXT-DECORATION: none;}
table,td{ border: 1px solid #ffffff }
</style>
</head>
<body>
<?php
@$month=$_GET['month'];
@$year=$_GET['year'];
if(!($month <13 and $month >0)){
$month =date("m"); // Current month as default month
}
if(!($year <=$end_year and $year >=$start_year)){
$year =date("Y"); // Set current year as default year
}
$d= 2; // To Finds today's date
//$no_of_days = date('t',mktime(0,0,0,$month,1,$year)); //This is to calculate number of days in a month
$no_of_days = cal_days_in_month(CAL_GREGORIAN, $month, $year);//calculate number of days in a month
$j= date('w',mktime(0,0,0,$month,1,$year)); // This will calculate the week day of the first day of the month
//echo $j;
$adj=str_repeat("<td bgcolor='#ffff00'>* </td>",$j); // Blank starting cells of the calendar
$blank_at_end=42-$j-$no_of_days; // Days left after the last day of the month
if($blank_at_end >= 7){$blank_at_end = $blank_at_end - 7 ;}
$adj2=str_repeat("<td bgcolor='#ffff00'>* </td>",$blank_at_end); // Blank ending cells of the calendar
/// Starting of top line showing year and month to select ///////////////
echo "<table class='main'><td colspan=6 >
<select name=month value='' onchange="reload(this.form)" id="month">
<option value=''>Select Month</option>";
for($p=1;$p<=12;$p++){
$dateObject = DateTime::createFromFormat('!m', $p);
$monthName = $dateObject->format('F');
if($month==$p){
echo "<option value=$p selected>$monthName</option>";
}else{
echo "<option value=$p>$monthName</option>";
}
}
echo "</select>
<select name=year value='' onchange="reload(this.form)" id="year">Select Year</option>
";
for($i=$start_year;$i<=$end_year;$i++){
if($year==$i){
echo "<option value='$i' selected>$i</option>";
}else{
echo "<option value='$i'>$i</option>";
}
}
echo "</select>";
echo " </td><td align='center'><a href=# onClick='self.close();'>X</a></td></tr><tr>";
echo "<th>Sun</th><th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th>Sat</th></tr><tr>";
////// End of the top line showing name of the days of the week//////////
//////// Starting of the days//////////
for($i=1;$i<=$no_of_days;$i++){
$onclick = sprintf('post_value(%d,%d,%d); return false;', $month, $i, $year);
echo $adj . '<td><a href="#" onclick="' . htmlspecialchars($onclick, ENT_QUOTES, 'UTF-8') . '">' . $i . '</a>'; // Display the date inside the calendar cell
echo " </td>";
$adj='';
$j ++;
if($j==7){echo "</tr><tr>"; // start a new row
$j=0;}
}
echo $adj2; // Blank the balance cell of calendar at the end
echo "<tr><td colspan=7 align=center><a href='https://www.plus2net.com'><b>plus2net.com Calendar</b></a></td></tr>";
echo "</tr></table>";
echo "<center><a href=cal2.php>Reset PHP Calendar</a></center>";
?>
</body>
</html>
.
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.
| bryan | 02-12-2013 |
| i have a problem with the php file. when i want to chande the to the next month it only comes back with the php file and not the correct month | |
| Anthony Aniah | 22-04-2015 |
| This tutorial is superb. its version in my vernacular.Thus, 1=iken, 2=ife, 3=ikie, 4=inde, 5=idiong, 6=idiong-iken, 7=idiong-ife, 8=idiong-ikie, 9=idiong-inde, 10=liwho. So, how can I make this appear correspondingly on the same calender? Then, katube, ugidi, azule, lifedian, lifembe are the five primitive days in my vernacular against seven days in a week as monday to sunday. How can i make a valid calender out of these variants? I realy need help. Please. | |
| madi | 21-12-2016 |
| does the code even work? it just gives me an empty dropdown | |
| smo1234 | 19-02-2017 |
| Code works fine, new two years added, now you can use yearly calendars for 2017. You can generate any year calendar by changing the year variable. | |