Skip to main content
GameDev.net gamedev.net
🔒 Locked 🤖 Godot

Finally! I successfully implemented a calendar in PHP!

Started by liquidAir May 31, 2005 at 2:45 AM 15 replies 3.5k views
Original Post
liquidAir
liquidAir
About a year ago, this was very difficult to achieve. I just decided to drop the idea. Last night, I picked up the idea, started coding this morning, for about 30 minutes and it worked! And I am very happy! And it's very easy to use! Well, all you have to do is call the function displayCalendar(month, year) where month is a string representing the month you want, e.g. "January", and year is an integer. I did not do any error checking for invalid years (hopefully, anyone using it will be sensible enough not to go beyond the limits? Although I know there are people who are always willing to break code [grin]) It uses tables for layout... uh... it's not feasible for you to use absolute positioning with this, except you're insane. Anyways, here's the code:

<?

// PHP Calendar Helper Functions/Script
// Copyright (C) 2005 Akinwale Ariwodola

// Default styles - add this to your stylesheet or style tag
// .calendarBorder { background: #999 }
// .calendar TD { background: #FFF; font-family: Verdana, Arial, sans-serif;
// font-size: 10px; text-align: right }
// .calendarDays TD { background: #DDD; font-family: Verdana, Arial, sans-serif;
// font-size: 10px; font-weight: bold; text-align: right }

$monthsOfYear = array("January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December");

$daysOfWeek = array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");

$daysOfWeekS = array("S", "M", "T", "W", "T", "F", "S");

function getFirstDayOfMonthIndex($monthStr, $year)
{
  global $monthsOfYear, $daysOfWeek;

  $monthIndex = 0;

  for($i = 0; $i < count($monthsOfYear); $i++)
  {
    if(strcmp($monthsOfYear[$i], $monthStr) == 0)
    {
      $monthIndex = $i;
    }
  }

  $firstdayStr = date("l", mktime(0, 0, 0, ($monthIndex + 1), 1, $year));

  for($index = 0; $index < count($daysOfWeek); $index++)
  {
    if(strcmp($daysOfWeek[$index], $firstdayStr) == 0)
    {
      return $index;
    }
  }
}

function getCurrentYear()
{
  return intval(date("Y"));
}

function getCurrentMonthStr()
{
  return date("F");
}

function getCurrentDayIndex()
{
  global $daysOfWeek;

  for($i = 0; $i < count($daysOfWeek); $i++)
  {
    if(strcmp($daysOfWeek[$i], date("l")) == 0)
    {
      return $i;
    }
  }
}

function getCurrentMonthIndex()
{
  global $monthsOfYear;

  for($i = 0; $i < count($monthsOfYear); $i++)
  {
    if(strcmp($monthsOfYear[$i], date("F")) == 0)
    {
      return $i;
    }
  }
}

function isLeapYear($year)
{
  if($year % 4 == 0 && (($year % 100 != 0) || ($year % 400 == 0)))
  {
    return 1;
  }

  return 0;
}

function getNumDaysInMonth($monthStr, $year)
{
  $retval = 0;

  switch($monthStr)
  {
    case "January": $retval = 31; break;
    case "February": $retval = (isLeapYear($year)) ? 29 : 28; break;
    case "March": $retval = 31; break;
    case "April": $retval = 30; break;
    case "May": $retval = 31; break;
    case "June": $retval = 30; break;
    case "July": $retval = 31; break;
    case "August": $retval = 31; break;
    case "Septebmer": $retval = 30; break;
    case "October": $retval = 31; break;
    case "November": $retval = 30; break;
    case "December": $retval = 31; break;
  }

  return $retval;
}

// simply call this function with the month string, and the year you want to display
function displayCalendar($monthStr, $year)
{
  $numdays = getNumDaysInMonth($monthStr, $year);
  $firstdayIndex = getFirstDayOfMonthIndex($monthStr, $year);

  $preCols = 0;

  echo "<table class=\"calendarBorder\" cellspacing=\"0\" cellpadding=\"0\"><tr><td width=\"100%\">\n";
  echo "<table class=\"calendar\" cellspacing=\"1\" cellpadding=\"3\">\n";
  echo "<tr class=\"calendarDays\"><td>S</td> <td>M</td> <td>T</td> <td>W</td>
<td>T</td> <td>F</td> <td>S</td></tr>\n";

  for($pre = 0; $pre < $firstdayIndex; $pre++)
  {
    if($pre == 0)
    {
      echo "<tr>\n";
    }

    echo "<td></td>\n";
    $preCols += 1;
  }

  for($i = 0; $i < $numdays; $i++)
  {
    if(($i + $preCols) % 7 == 0)
    {
      echo "</tr>\n<tr>";
    }
    echo "<td style=\"text-align: right\">" . ($i + 1). "</td>\n";
  }

  echo "</table></td></tr></table>\n";
}

?>
MrWeet
MrWeet
Nice job! Excellent calendar, especially for 30 minutes of work.
Professional-Noob Guitarist : Don't try to play the music, you have to feel it!
capn_midnight
capn_midnight
function getNumDaysInMonth($monthStr, $year){  $retval = 0;  switch($monthStr)  {    case "January": $retval = 31; break;    case "February": $retval = (isLeapYear($year)) ? 29 : 28; break;    case "March": $retval = 31; break;    case "April": $retval = 30; break;    case "May": $retval = 31; break;    case "June": $retval = 30; break;    case "July": $retval = 31; break;    case "August": $retval = 31; break;    case "Septebmer": $retval = 30; break;    case "October": $retval = 31; break;    case "November": $retval = 30; break;    case "December": $retval = 31; break;  }  return $retval;}


PHP has associative arrays that allows you to index arrays with strings. In fact, I couldn't quite remember the syntax, so I searched google, and the example I found was for days of the month
$mdays = array (		"January" => 31,		"February" => 28,		"March" => 31,		"April" => 30,		"May" => 31,		"June" => 30,		"July" => 31,		"August" => 31,		"September" => 30,		"October" => 31,		"November" => 30,		"December" => 31		);

scheisskopf
scheisskopf
I prefer something like:

exec('cal');

:)
TomX
TomX
Congratz :)

PHP is probably my favourite language, the only reason I don't use it most is because it's least useful out of it and Java, well least useful in terms of the type of programming I do.
CGameProgrammer
CGameProgrammer
Quote:
Original post by scheisskopf
I prefer something like:

exec('cal');

:)

Nah, this is the best:
`cal`;
~CGameProgrammer( ); Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
tstrimp
tstrimp
I strongly suggest the OP look into the Date() function in php. You could have saved some work in there.

Edit: Okay it looks like he did use date(), could have used it more though.
tstrimp
tstrimp
Here is the one I built around a month ago (Edit: Aparently it was built on 5/11 :D). I decided to keep the data separate from the look and feel so this class only returns a multi-dimensional array containing the layout for the month so that you can make it look whatever fits best on the site without changing the calendar code at all.

I might add the ability to return a generic html calendar but for now it's perfectly useable the way it is.

<?phpdefine("SECOND", 1);define("MINUTE", SECOND * 60);define("HOUR", MINUTE * 60);define("DAY", HOUR * 24);/*********************************************************************************	class Calendar	05/11/05 - 22:26:50/*********************************************************************************/class Calendar{	var $months, $month, $year, $day;	var $caldata;	/*********************************************************************************		string Calendar($month, $year);		05/11/05 - 22:27:46		Function Description:			This is the class constructor. It sets the month and year based			off of the data passed in. If no data is passed in it sets the			month and year based off of today. Constructors have no return			value.	/*********************************************************************************/	function Calendar($month = false, $year = false, $day = false)	{		if($month === false)		{			$month = date('n');		}		if($year == false)		{			$year = date('Y');		}		if($day == false)		{			$day = date('d');		}		while($month > 12)		{			$month -= 12;			$year++;		}		while($month < 1)		{			$month += 12;			$year--;		}		$this->months = array(1 => 'January', 2 => 'February', 3 => 'March', 4 => 'April', 5 => 'May', 6 => 'June', 7 => 'July', 8 => 'August', 9 => 'September', 10 => 'October', 11 => 'November', 12 => 'December');		$this->month = $month;		$this->year = $year;		$this->day = $day;		$this->CalulateCalendarData();	}	//	Calendar();	/*********************************************************************************		int GetMonth(void);		05/11/05 - 22:30:16		Function Description:			This function returns the value of the month in numeric form.	/*********************************************************************************/	function GetMonth()	{		return $this->month;	}	//	GetMonth();	/*********************************************************************************		string GetMonthName(void);		05/11/05 - 22:30:16		Function Description:			This function returns the value of the month in numeric form.	/*********************************************************************************/	function GetMonthName($month = false)	{		if($month == false)		{			$month = $this->GetMonth();		}		return $this->months[$month];	}     //     GetMonthName();	/*********************************************************************************		void SetMonth(month);		05/11/05 - 22:30:16		Function Description:			This function sets the month value.	/*********************************************************************************/	function SetMonth()	{		$this->month = $month;		$this->CalulateCalendarData();	}	//	SetMonth();	/*********************************************************************************		int GetYear(void);		05/11/05 - 22:30:16		Function Description:			This function returns the value of the year in numeric form.	/*********************************************************************************/	function GetYear()	{		return $this->year;	}	//	GetYear();	/*********************************************************************************		void SetYear(month);		05/11/05 - 22:30:16		Function Description:			This function sets the year value.	/*********************************************************************************/	function SetYear()	{		$this->month = $month;		$this->CalulateCalendarData();	}	//	SetYear();	/*********************************************************************************		array GetCalendarData(void);		05/11/05 - 22:35:52		Function Description:			This function returns a 2 dimensional array containing the layout of a			calendar including blank days.	/*********************************************************************************/	function GetCalendarData()	{		return $this->caldata;	}	//	GetCalendarData();	/*********************************************************************************		int MonthDays(void);		05/11/05 - 22:41:28		Function Description:			This function returns the total days in the month.	/*********************************************************************************/	function MonthDays()	{		return date('t', $this->GetTimestamp());	}	//	MonthDays();	/*********************************************************************************		int GetTimestamp(int);		05/11/05 - 22:45:27		Function Description:			This function returns a timestamp of the current date.	/*********************************************************************************/	function GetTimestamp($day = false)	{		if($day == false)		{			$day = $this->day;		}		return mktime(0, 0, 0, $this->month, $day, $this->year);	}	//	FunctionName();	/*********************************************************************************		int FirstDay(void);		05/11/05 - 22:45:27		Function Description:			This function returns the first day of the week as an integer.	/*********************************************************************************/	function FirstDay()	{		return date('w', mktime(0, 0, 0, $this->month, 1, $this->year));	}	//	FirstDay();	/*********************************************************************************		int GetNextMonth(void);		05/11/05 - 22:45:27		Function Description:	/*********************************************************************************/	function GetNextMonth()	{		return new Calendar($this->GetMonth() + 1, $this->GetYear());	}	//	GetNextMonth();	/*********************************************************************************		int GetPrevMonth(void);		05/11/05 - 22:45:27		Function Description:	/*********************************************************************************/	function GetPrevMonth()	{		return new Calendar($this->GetMonth() - 1, $this->GetYear());	}	//	GetPrevMonth();	/*********************************************************************************		array CalulateCalendarData(void);		05/11/05 - 22:35:52		Function Description:			This function is called whenever the month or year is set. It will populate			the caldata member variable with the information needed to display a calendar.	/*********************************************************************************/	function CalulateCalendarData()	{		$count = 1;		$start = false;		$week = 0;		$data = array();		while($count <= $this->MonthDays())		{			$week++;			for($i = 0; $i < 7; $i++)			{				if($i == $this->FirstDay())				{					$start = true;				}				if($count > $this->MonthDays())				{					$start = false;				}				$val = false;				if($start)				{					$val = array('day' => $count, 'start' => $this->GetTimestamp($count), 'end' => $this->GetTimestamp($count) + DAY - 1);					$count++;				}				$data[$week][$i] = $val;			}		}		$this->caldata = $data;	}	//	CalulateCalendarData();}	//	Class Calendar();?>
GroZZleR
GroZZleR
Quote:
Original post by capn_midnight
PHP has associative arrays that allows you to index arrays with strings. In fact, I couldn't quite remember the syntax, so I searched google, and the example I found was for days of the month


I don't see an issue with his solution as he has to calculate if it's a leap year or not.

Personally I would of done this instead (as I am quite lazy):
function getNumDaysInMonth($monthStr, $year){  switch($monthStr)  {    case "February": return (isLeapYear($year)) ? 29 : 28; break;    case "April": case "June": case "September": case "November": return 30; break;    default: return 31; break;  }}
tstrimp
tstrimp
Quote:
Original post by GroZZleR
Quote:
Original post by capn_midnight
PHP has associative arrays that allows you to index arrays with strings. In fact, I couldn't quite remember the syntax, so I searched google, and the example I found was for days of the month


I don't see an issue with his solution as he has to calculate if it's a leap year or not.

Personally I would of done this instead (as I am quite lazy):
*** Source Snippet Removed ***


I would have just used the date function to get the total number of days in the month for that year. [razz]

    date('t', mktime ( 0, 0, 0, $month, 1, $year));   // $month is an integer 1 - 12
liquidAir
liquidAir
Quote:
Original post by GroZZleR
Quote:
Original post by capn_midnight
PHP has associative arrays that allows you to index arrays with strings. In fact, I couldn't quite remember the syntax, so I searched google, and the example I found was for days of the month


I don't see an issue with his solution as he has to calculate if it's a leap year or not.

Personally I would of done this instead (as I am quite lazy):
*** Source Snippet Removed ***


LOL. I was contemplating doing this, but then, your code starts to get unreadable. Well, I wasn't able to access any PHP documentation so I was unable to see the kinds of possibilities with the date function that I haven't used before.
Deranged
Deranged
Quote:
Original post by tstrimp
Quote:
Original post by GroZZleR
Quote:
Original post by capn_midnight
PHP has associative arrays that allows you to index arrays with strings. In fact, I couldn't quite remember the syntax, so I searched google, and the example I found was for days of the month


I don't see an issue with his solution as he has to calculate if it's a leap year or not.

Personally I would of done this instead (as I am quite lazy):
*** Source Snippet Removed ***


I would have just used the date function to get the total number of days in the month for that year. [razz]

*** Source Snippet Removed ***


Yeah but you would still have to use a long switch-case to convert monthStr to the numbermonth, if i know my mktime correctly.
tstrimp
tstrimp
Quote:
Original post by DerAnged
Yeah but you would still have to use a long switch-case to convert monthStr to the numbermonth, if i know my mktime correctly.


Thats part of the problem with using the month name to begin with. None of the php functions use it by name. Instead of a switch case he could base it off of the key in his $monthsOfYear function. The function would look like.

function getNumDaysInMonth($monthStr, $year){   GLOBAL $monthsOfYear;   return date('t', mktime ( 0, 0, 0, array_keys($monthsOfYear, $monthStr) + 1, 1, $year));}


Of course all that messyness could be avoided by using a numeric valuefor the month instead.

edit: Forgot the return
coldacid
coldacid
Nvu has some special thingo that does a calendar in &#106avascript. I toyed around with it once and got it to do stuff when dates are clicked and show months other than the current, without needing to reload the page.<br/><br/>Still, PHP is superior to &#106avascript, so all I've done here is increase my post count. Yay me.
tstrimp
tstrimp
Quote:
Original post by coldacid
Nvu has some special thingo that does a calendar in &#106avascript. I toyed around with it once and got it to do stuff when dates are clicked and show months other than the current, without needing to reload the page.

Still, PHP is superior to &#106avascript, so all I've done here is increase my post count. Yay me.<!--QUOTE--></td></tr></table></BLOCKQUOTE><!--/QUOTE--><!--ENDQUOTE--><br><br>Those &#106avascript &#111;nes are great for input &#111;n forms!</td></tr></table></blockquote>
coldacid
coldacid
That's true enough, but day/month dropdowns and a textbox for year are generally quicker than navigating a calendar anyway.
capn_midnight
capn_midnight
Quote:
Original post by coldacid
PHP is superior to &#106avascript<!--QUOTE--></td></tr></table></BLOCKQUOTE><!--/QUOTE--><!--ENDQUOTE--><br>once again, comparing two fundamentally different things.<br><br></td></tr></table></blockquote>

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.