Skip to the content...

Welcome to the David Walsh Blog. I'm a MooTools, Dojo, jQuery, CSS, and PHP Web Developer located in Madison, Wisconsin, United States. Please contact me if I can make your experience on my website better.

Build a Calendar Using PHP, XHTML, and CSS

56 Responses »
PHP Calendar

One of the website features my customers love to provider their web users is an online dynamic calendar. An online calendar can be used for events, upcoming product specials, memos, and anything else you can think of. I've taken some time to completely rewrite the PHP event calendar so that I may share it with you.

The CSS

/* calendar */
table.calendar		{ border-left:1px solid #999; }
tr.calendar-row	{  }
td.calendar-day	{ min-height:80px; font-size:11px; position:relative; } * html div.calendar-day { height:80px; }
td.calendar-day:hover	{ background:#eceff5; }
td.calendar-day-np	{ background:#eee; min-height:80px; } * html div.calendar-day-np { height:80px; }
td.calendar-day-head { background:#ccc; font-weight:bold; text-align:center; width:120px; padding:5px; border-bottom:1px solid #999; border-top:1px solid #999; border-right:1px solid #999; }
div.day-number		{ background:#999; padding:5px; color:#fff; font-weight:bold; float:right; margin:-5px -5px 0 0; width:20px; text-align:center; }
/* shared */
td.calendar-day, td.calendar-day-np { width:120px; padding:5px; border-bottom:1px solid #999; border-right:1px solid #999; }

The above code is complete with IE6 hacks.

The PHP

/* draws a calendar */
function draw_calendar($month,$year){

	/* draw table */
	$calendar = '<table cellpadding="0" cellspacing="0" class="calendar">';

	/* table headings */
	$headings = array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
	$calendar.= '<tr class="calendar-row"><td class="calendar-day-head">'.implode('</td><td class="calendar-day-head">',$headings).'</td></tr>';

	/* days and weeks vars now ... */
	$running_day = date('w',mktime(0,0,0,$month,1,$year));
	$days_in_month = date('t',mktime(0,0,0,$month,1,$year));
	$days_in_this_week = 1;
	$day_counter = 0;
	$dates_array = array();

	/* row for week one */
	$calendar.= '<tr class="calendar-row">';

	/* print "blank" days until the first of the current week */
	for($x = 0; $x < $running_day; $x++):
		$calendar.= '<td class="calendar-day-np"> </td>';
		$days_in_this_week++;
	endfor;

	/* keep going with days.... */
	for($list_day = 1; $list_day <= $days_in_month; $list_day++):
		$calendar.= '<td class="calendar-day">';
			/* add in the day number */
			$calendar.= '<div class="day-number">'.$list_day.'</div>';

			/** QUERY THE DATABASE FOR AN ENTRY FOR THIS DAY !!  IF MATCHES FOUND, PRINT THEM !! **/
			$calendar.= str_repeat('<p> </p>',2);
			
		$calendar.= '</td>';
		if($running_day == 6):
			$calendar.= '</tr>';
			if(($day_counter+1) != $days_in_month):
				$calendar.= '<tr class="calendar-row">';
			endif;
			$running_day = -1;
			$days_in_this_week = 0;
		endif;
		$days_in_this_week++; $running_day++; $day_counter++;
	endfor;

	/* finish the rest of the days in the week */
	if($days_in_this_week < 8):
		for($x = 1; $x <= (8 - $days_in_this_week); $x++):
			$calendar.= '<td class="calendar-day-np"> </td>';
		endfor;
	endif;

	/* final row */
	$calendar.= '</tr>';

	/* end the table */
	$calendar.= '</table>';
	
	/* all done, return result */
	return $calendar;
}

/* sample usages */
echo '<h2>July 2009</h2>';
echo draw_calendar(7,2009);

echo '<h2>August 2009</h2>';
echo draw_calendar(8,2009);

The PHP is largely based upon one function that only requires the month and year of the calendar you'd like. It's a sizeable function but obviously worth its weight in gold. Also note that I've identified a spot within the calendar where you should query the database to see if there are any events for that day. I use tables because they nicely stretch when one day in the week is longer than others. Working with absolute positioning and DIVs in the calendar is far too much hassle for a simple calendar.

I look forward to seeing what you can do with the calendar!

Discussion

  1. July 16, 2009 @ 8:01 am

    That takes me back.
    One of the first things I ever used mootools for was to build 2 calendars.
    Personally I hate tables, so I did it table less.

    One of the places specifically wanted a calendar with NO weekends. Other other was a project of my own. To create a calendar that would deal with 50+ events on a single day in a usable fashion.

    Looking at them now reminds me of just how far I have come.
    you can see them here.
    http://osl.risd.edu/calendar/index.php
    http://www.respond-design.org/index.php?month=2&year=2009

  2. July 16, 2009 @ 9:20 am

    Sweet! I’ve been trying to psych myself into doing this and rebuild a whole events page I have. I’ve been using a JavaScript-based calendar and it works but… This just looks some much cleaner and probably will get searched better by the spiders. Thanks for a big start on my events page rewrite!

  3. July 16, 2009 @ 9:34 am

    That’s some pretty good code David, but google calendar really makes all other calendars obsolete, it’s just so easy and logical to use.

  4. rodreego nascimento
    July 16, 2009 @ 1:19 pm

    Awesome. Thanks very helpfull.

  5. July 16, 2009 @ 2:47 pm

    This is great. I just finished figuring out how to make a php calendar myself about 3wks ago to use in symfony. I will probably borrow a few ideas from you to update my calendar.

  6. louis w
    July 16, 2009 @ 5:24 pm

    Nice tutorial, your right this is a feature request that often comes up. I would suggest you do one query to the db before the loop and just check the returned data for each day. Would cut down on the overhead of doing a hit for every day.

    @Adriaan: I have to disagree, while Google Calendar is wonderful and I use it myself, having a custom calendar integrated into your website/application is quite often superior.

  7. July 16, 2009 @ 6:27 pm

    @Louis W: That would be a good idea, but I wanted to keep it simple for the sake of this article. If I started preaching database, the article would’ve been a mile long. :)

  8. July 18, 2009 @ 4:40 am

    It will be best if you make it event calender, i can use it ;)
    Thanks!

  9. July 19, 2009 @ 9:46 pm

    Excellent coding!

    Line 12 (PHP snippet): ‘w’ needs quoted.

    I used the following code for calendar events. You need to include the arrays as arguments to the function signature if you populate them externally (or use global array/keyword).

    /* QUERY THE DATABASE FOR AN ENTRY FOR THIS DAY !! IF MATCHES FOUND, PRINT THEM !! */
    $keys = array(‘comment’, ‘shout’, ‘submission’);

    foreach ($keys as $key) {
    ${$key . ‘_events’} = 0;
    foreach (${$key . ‘s’} as $event) {

    $event_datetime = strtotime($event[$key . '_datetime']);
    $event_day = date(‘j’, $event_datetime);
    $event_month = date(‘F’, $event_datetime);
    $event_year = date(‘Y’, $event_datetime);

    $now_datetime = mktime(0, 0, 0, $month, $list_day, $year);
    $now_day = date(‘j’, $now_datetime);
    $now_month = date(‘F’, $now_datetime);
    $now_year = date(‘Y’, $now_datetime);

    if (($event_day == $now_day) && ($event_month == $now_month) && ($event_year == $now_year)) {
    ${$key . ‘_events’} += 1;
    }

    }
    if (${$key . ‘_events’} > 0) $calendar .= ‘<div class=”calendar-event ‘ . $key . ‘”>’ . ${$key . ‘_events’} . ‘ ‘ . $key . (${$key . ‘_events’} > 1 ? ‘s’ : ” ) . ‘</div>’;

    }

  10. July 20, 2009 @ 3:02 am

    Instead of using the table cellpadding and cellspacing put the padding in the CSS and the spacing-glitches you can fend off using border-collapse:collapse for the table. Remember to then put margin and padding on the td’s and the th’s.

  11. July 20, 2009 @ 7:24 am

    @Sebastiaan: Margin on the TD’s and TH’s? That wont work.

  12. July 20, 2009 @ 7:41 am

    Here’s my slightly revised code, works like a charm on all major Windblows browsers (only IE6 doesn’t do the hover-thing):

    print(“table.calendar { border-left:1px solid #999; border-collapse:collapse; }
    tr.calendar-row { }
    td.calendar-day { min-height:80px; font-size:1.0em; position:relative; margin:0; padding:0; }
    * html div.calendar-day { height:80px; }
    td.calendar-day:hover { background-color:#eceff5; margin:0; padding:5px; }
    td.calendar-day-np { background-color:#eee; margin:0; padding:0; min-height:80px; }
    * html div.calendar-day-np { height:80px; }
    td.calendar-day-head { background-color:#ccc; font-weight:bold; text-align:center; width:120px; padding:5px; margin:0; border-bottom:1px solid #999; border-top:1px solid #999; border-right:1px solid #999; }
    div.day-number { background:#999; padding:5px; color:#fff; font-weight:bold; float:right; margin:-5px -5px 0 0; width:20px; text-align:center; }
    td.calendar-day, td.calendar-day-np { width:120px; padding:5px; border-bottom:1px solid #999; border-right:1px solid #999; margin:0; }”);

  13. July 20, 2009 @ 7:42 am

    Of course removing the cellpadding and cellspacing parameters in the table-tag.

  14. July 20, 2009 @ 7:48 am

    @Sebastiaan – Ah…for margin on cells you’d have to use a combination of border-spacing and border-collapse. These are not fully supported by our special friend though, so you’re better off using cellspacing and cellpadding, like David suggests :)

  15. July 20, 2009 @ 8:15 am

    Yeah, but I’m a standardista so I prefer NOT to use any inline styles or parameters on a tag that should be in a CSS. So IE6 users won’t get the desired effect, but no lack in functionality. The whole idea of my initial comment was removing the cellpadding and cellspacing from the table-tag ;-) My changes actually work in IE6, they only won’t get the hover effect, but that was so in the original code as well!

  16. July 23, 2009 @ 6:47 am

    Hello from Spain and thanks for the script. My small contribution: if you want to start your calendar week on monday, change print(” $running_day = date(‘w’,mktime(0,0,0,$month,1,$year))”); to print( $running_day = date(‘w’,mktime(0,0,0,$month,1,$year))-1;”); see you.

  17. steve davis
    July 29, 2009 @ 4:57 pm

    Can someone throw me a bone? The basic calendar is displayed, but is not formated like the demo (maybe css issue) and when I attempted to implement the controls, I don’t see them at all. Can someone help me out?

  18. July 29, 2009 @ 4:59 pm

    @Steve: can you post your code somewhere or give us the URL to the live page?

  19. steve davis
    July 29, 2009 @ 6:03 pm

    http://www.davislegal.net/MyPACE/calendar.php

    Thanks for any help you can provide.

    Steve

  20. steve davis
    July 29, 2009 @ 6:07 pm

    css file
    /* calendar /
    table.calendar { border-left:1px solid #999; }
    tr.calendar-row { }
    td.calendar-day { min-height:80px; font-size:11px; position:relative; } * html div.calendar-day { height:80px; }
    td.calendar-day:hover { background:#eceff5; }
    td.calendar-day-np { background:#eee; min-height:80px; } * html div.calendar-day-np { height:80px; }
    td.calendar-day-head { background:#ccc; font-weight:bold; text-align:center; width:120px; padding:5px; border-bottom:1px solid #999; border-top:1px solid #999; border-right:1px solid #999; }
    div.day-number { background:#999; padding:5px; color:#fff; font-weight:bold; float:right; margin:-5px -5px 0 0; width:20px; text-align:center; }
    /
    shared */
    td.calendar-day, td.calendar-day-np { width:120px; padding:5px; border-bottom:1px solid #999; border-right:1px solid #999; }

  21. steve davis
    July 29, 2009 @ 7:33 pm

    <?
    /* date settings */
    $month = (int) ($_GET['month'] ? $_GET['month'] : date('m'));
    $year = (int) ($_GET['year'] ? $_GET['year'] : date('Y'));

    /* select month control */
    $select_month_control = '’;
    for($x = 1; $x <= 12; $x++) {
    $select_month_control.= '’.date(‘F’,mktime(0,0,0,$x,1,$year)).”;
    }
    $select_month_control.= ”;

    /* select year control */
    $year_range = 7;
    $select_year_control = ”;
    for($x = ($year-floor($year_range/2)); $x <= ($year+floor($year_range/2)); $x++) {
    $select_year_control.= '’.$x.”;
    }
    $select_year_control.= ”;

    /* “next month” control */
    $next_month_link = ‘Next Month >>‘;

    /* “previous month” control */
    $previous_month_link = ‘<< Previous Month‘;

    /* bringing the controls together */
    $controls = ”.$select_month_control.$select_year_control.’ ‘.$previous_month_link.’ ‘.$next_month_link.’ ‘;
    echo ‘November 2009′;
    echo draw_calendar(11,2009);
    ?>

    <?
    /* draws a calendar */
    function draw_calendar($month,$year){

    /* draw table */
    $calendar = '’;

    /* table headings */
    $headings = array(‘Sunday’,'Monday’,'Tuesday’,'Wednesday’,'Thursday’,'Friday’,'Saturday’);
    $calendar.= ”.implode(”,$headings).”;

    /* days and weeks vars now … */
    $running_day = date(‘w’,mktime(0,0,0,$month,1,$year));
    $days_in_month = date(‘t’,mktime(0,0,0,$month,1,$year));
    $days_in_this_week = 1;
    $day_counter = 0;
    $dates_array = array();

    /* row for week one */
    $calendar.= ”;

    /* print “blank” days until the first of the current week */
    for($x = 0; $x < $running_day; $x++):
    $calendar.= ' ‘;
    $days_in_this_week++;
    endfor;

    /* keep going with days…. */
    for($list_day = 1; $list_day <= $days_in_month; $list_day++):
    $calendar.= '’;
    /* add in the day number */
    $calendar.= ”.$list_day.”;

    /** QUERY THE DATABASE FOR AN ENTRY FOR THIS DAY !! IF MATCHES FOUND, PRINT THEM !! **/
    /* $keys = array(’comment’, ’shout’, ’submission’);

    foreach ($keys as $key) {
    ${$key . ‘_events’} = 0;
    foreach (${$key . ’s’} as $event) {

    $event_datetime = strtotime($event[$key . '_datetime']);
    $event_day = date(’j’, $event_datetime);

    $event_month = date(’F’, $event_datetime);
    $event_year = date(’Y’, $event_datetime);

    $now_datetime = mktime(0, 0, 0, $month, $list_day, $year);
    $now_day = date(’j’, $now_datetime);
    $now_month = date(’F’, $now_datetime);
    $now_year = date(’Y’, $now_datetime);

    if (($event_day == $now_day) && ($event_month == $now_month) && ($event_year == $now_year)) {
    ${$key . ‘_events’} += 1;
    }

    }
    if (${$key . ‘_events’} > 0) $calendar .= ‘’ . ${$key . ‘_events’} . ‘ ‘ . $key . (${$key . ‘_events’} > 1 ? ’s’ : ” ) . ‘’;

    }
    */
    // end of events array

    $calendar.= str_repeat(‘ ‘,2);

    $calendar.= ”;
    if($running_day == 6):
    $calendar.= ”;
    if(($day_counter+1) != $days_in_month):
    $calendar.= ”;
    endif;
    $running_day = -1;
    $days_in_this_week = 0;
    endif;
    $days_in_this_week++; $running_day++; $day_counter++;
    endfor;

    /* finish the rest of the days in the week */
    if($days_in_this_week < 8):
    for($x = 1; $x <= (8 – $days_in_this_week); $x++):
    $calendar.= ' ‘;
    endfor;
    endif;

    /* final row */
    $calendar.= ”;

    /* end the table */
    $calendar.= ”;

    /* all done, return result */
    return $calendar;
    }

    /* sample usages
    echo ‘November 2009′;
    echo draw_calendar(11,2009);

    echo ‘August 2009′;
    echo draw_calendar(8,2009);
    */
    ?>

  22. darfuria
    August 10, 2009 @ 10:51 am

    I love Google Calendar, but I’ve recently started a project that requires me to setup a calendar for about 800 years ago, which isn’t something Google Calendar handles very well. This looks like it could do the job, as the year can be specified, so great, thanks!

  23. August 13, 2009 @ 2:26 am

    There are many calender scripts out there, but I found this one pretty simple yet fully working,

  24. August 20, 2009 @ 3:49 am

    Just wanted to thank and give you credit for this open source of code. I manipulated it into a class for a framework (as well as free standing php) so folks can just call the instance of the class and develop the calendar in a matter of 4 or 5 lines of code. Best part is, say you needed multiple calendars on a site, you can call the class for each section and even define the styling for different calendars (if you wanted a small one on your main page – but a big one on the actual calendar page w/e)

    Here’s a link to the thread in which the information was posted about the class and styling. Thanks again :)

    http://www.yiiframework.com/forum/index.php?/topic/3889-free-form-calendar-application/

  25. mike
    September 16, 2009 @ 9:11 am

    nice script

    I think that your final row of empty cells may be missing an opening tag

    have you tried validating the html output by the script?

  26. maciej
    September 29, 2009 @ 3:06 am

    @Spielberg: I guess it doesn’t work correctly for months starting on Sunday – first week gets 8 days.

  27. mario
    October 9, 2009 @ 8:35 am

    If I actually want the dates/day numbers of the leading/trailing days in this part:

    /* print “blank” days until the first of the current week */
    for($x = 0; $x < $running_day; $x++):
    $calendar.= ' ’;
    $days_in_this_week++;
    endfor;

    How do I go about doing that?

  28. mario
    October 9, 2009 @ 8:55 am

    If you want to get the actual days in the last month which run into the 1st week of the displayed month, I used:

    $daysInLastMonth = date(‘t’,mktime(0,0,0,$month-1,1,$year));

    /* print “blank” days until the first of the current week */
    for($x = 0; $x < $runningDay; $x++):
    $calendar.= '’ . ( ( $daysInLastMonth – ( $runningDay – 1 ) ) + $x ). ”;
    $daysInThisWeek++;
    endfor;

  29. andy
    October 22, 2009 @ 4:37 pm

    Thank you soooooo much. Been looking for a really simple one to incorporate with my mysql db and this is it! Again, thank you!

  30. October 26, 2009 @ 9:00 am

    Thanks a lot for this excellent and easy code ! I really like it !

  31. jonas
    October 29, 2009 @ 10:31 am

    @Maciej: Use this additional line (2. one):

    $running_day = date(‘w’,mktime(0,0,0,$month,1,$year));
    $running_day = ($running_day == 0?6:$running_day-1);

  32. October 30, 2009 @ 1:21 pm

    Thank you so much sir! I needed a calendar script and I took yours as a base and made it into a class.

    Check it out

    http://pastie.org/677092

  33. October 30, 2009 @ 1:32 pm

    I cleanit up a bit

    http://pastie.org/677111

  34. October 30, 2009 @ 3:01 pm

    and again. sorry for the spam

    http://pastie.org/677264

  35. November 14, 2009 @ 10:50 am

    Thanks for the script, this is great. I noticed in IE 8, IE * standards mode that if you hover the border of the table cells in the bottom and right disappear. It seems that IE 8 does not like: position:relative in the td.calendar-day. I removed it and it now seems to work correctly in IE 8 standards mode. Any reason as to why I should leave that in or does anybody have any ideas.

    I found a person who had similar problems here: http://www.webmasterworld.com/css/3920160.htm

  36. fede isas
    December 14, 2009 @ 7:33 pm

    Hi guys. This is an awesome piece of code. I’ve seen you’ve identified that make 30 queries would be un efficient, so…I’m driving crazy trying to figure out another way around. Any good ideas? Thanks a lot.

  37. December 24, 2009 @ 10:35 am

    This is just what I’m after. Will be modifying it slightly, but thanks for the starting point David.

  38. kingdeejay
    January 5, 2010 @ 4:35 am

    Is there a way I could add Clickable images into the calender so that I could display events on a particular date? Something like http://www.furnightclub.com/calendar.php

  39. January 5, 2010 @ 1:15 pm

    Helpful article. Thanks!

  40. hamada
    January 31, 2010 @ 7:38 am

    based on your code and the css-calendar from http://www.stefanoverna.com/log/create-astonishing-ical-like-calendars-with-jquery,
    i created a function to automate the calendar. But it needs some extra code to be able inserting events:

    function draw_calendar($month,$year){
    /* Tablehead*/
    $calendar = ”;

    $calendar.= ‘

    MoDiMi
    DoFrSa
    So

    ‘;

    /* date vars */
    $running_day = date(‘w’,mktime(0,0,0,$month,1,$year))-1;
    $days_in_month = date(‘t’,mktime(0,0,0,$month,1,$year));
    $today = date(j);
    $days_in_this_week = 0;
    $day_counter = 0;
    $dates_array = array();

    /* Zeile für die erste Zeile*/
    $calendar.= ‘
    ‘;

    /* berechnet die colspan, Anzahl leere Felder vor dem heutigen Tag */
    for($x = 0; $x < $running_day; $x++){
    $days_in_this_week++;
    $calendar.='’;
    }

    /* die weiteren Tage eintragen */
    for($list_day = 1; $list_day <= $days_in_month; $list_day++){
    /* Tagnummer einfügen */
    if($list_day == $today){
    $calendar.= '’.$list_day.”;
    $list_day++;
    }else{
    $calendar.= ”.$list_day.”;
    }
    if($running_day == 6){
    $calendar.= ”;

    if(($day_counter+1) != $days_in_month){
    $calendar.= ”;
    $running_day = -1;
    $days_in_this_week = 0;
    }
    }
    $days_in_this_week++; $running_day++; $day_counter++;
    }

    /* finish the rest of the days in the week */
    if($days_in_this_week <= 7){
    for($x = 1; $x <= (8 – $days_in_this_week); $x++){
    $calendar.= '’;
    }
    }

  41. hamada
    January 31, 2010 @ 10:49 am

    ^ didn’t show any html code: another try:
    <!– <?php
    function draw_calendar($month,$year){
    /* Die Tabelle Zeichnen */
    $calendar = '’;

    /* Tabellenkopf */
    $calendar.= ‘

    MoDiMi
    DoFrSa
    So

    ‘;

    /* Tage und Wochen ab diesem Monat */
    $running_day = date(‘w’,mktime(0,0,0,$month,1,$year))-1;
    $days_in_month = date(‘t’,mktime(0,0,0,$month,1,$year));
    $today = date(j);
    $days_in_this_week = 0;
    $day_counter = 0;
    $dates_array = array();

    /* Zeile für die erste Zeile*/
    $calendar.= ‘
    ‘;

    /* berechnet die colspan, Anzahl leere Felder vor dem heutigen Tag */
    for($x = 0; $x < $running_day; $x++){
    $days_in_this_week++;
    $calendar.='’;
    }

    /* die weiteren Tage eintragen */
    for($list_day = 1; $list_day <= $days_in_month; $list_day++){
    /* Tagnummer einfügen */
    if($list_day == $today){
    $calendar.= '’.$list_day.”;
    $list_day++;
    }else{
    $calendar.= ”.$list_day.”;
    }
    if($running_day == 6){
    $calendar.= ”;

    if(($day_counter+1) != $days_in_month){
    $calendar.= ”;
    $running_day = -1;
    $days_in_this_week = 0;
    }
    }
    $days_in_this_week++; $running_day++; $day_counter++;
    }

    /* finish the rest of the days in the week */
    if($days_in_this_week <= 7){
    for($x = 1; $x <= (8 – $days_in_this_week); $x++){
    $calendar.= '’;
    }
    }

    /* final row */
    $calendar.= ”;

    /* end the table */
    $calendar.= ‘

    MoDiMi
    DoFrSa
    So

    ‘;

    /* all done, return result */
    return $calendar;
    }
    $thismonth = date(‘n’,time());
    $thisyear = date(‘Y’,time());
    echo draw_calendar($thismonth,$thisyear);
    ?>
    –>

  42. hamada
    January 31, 2010 @ 10:50 am

    <!–
    <?php
    function draw_calendar($month,$year){
    /* Die Tabelle Zeichnen */
    $calendar = '’;

    /* Tabellenkopf */
    $calendar.= ‘

    MoDiMi
    DoFrSa
    So

    ‘;

    /* Tage und Wochen ab diesem Monat */
    $running_day = date(‘w’,mktime(0,0,0,$month,1,$year))-1;
    $days_in_month = date(‘t’,mktime(0,0,0,$month,1,$year));
    $today = date(j);
    $days_in_this_week = 0;
    $day_counter = 0;
    $dates_array = array();

    /* Zeile für die erste Zeile*/
    $calendar.= ‘
    ‘;

    /* berechnet die colspan, Anzahl leere Felder vor dem heutigen Tag */
    for($x = 0; $x < $running_day; $x++){
    $days_in_this_week++;
    $calendar.='’;
    }

    /* die weiteren Tage eintragen */
    for($list_day = 1; $list_day <= $days_in_month; $list_day++){
    /* Tagnummer einfügen */
    if($list_day == $today){
    $calendar.= '’.$list_day.”;
    $list_day++;
    }else{
    $calendar.= ”.$list_day.”;
    }
    if($running_day == 6){
    $calendar.= ”;

    if(($day_counter+1) != $days_in_month){
    $calendar.= ”;
    $running_day = -1;
    $days_in_this_week = 0;
    }
    }
    $days_in_this_week++; $running_day++; $day_counter++;
    }

    /* finish the rest of the days in the week */
    if($days_in_this_week <= 7){
    for($x = 1; $x <= (8 – $days_in_this_week); $x++){
    $calendar.= '’;
    }
    }

    /* final row */
    $calendar.= ”;

    /* end the table */
    $calendar.= ‘

    MoDiMi
    DoFrSa
    So

    ‘;

    /* all done, return result */
    return $calendar;
    }
    $thismonth = date(‘n’,time());
    $thisyear = date(‘Y’,time());
    echo draw_calendar($thismonth,$thisyear);
    ?>
    –>

  43. February 25, 2010 @ 12:19 pm

    Is there any chance the calendar can show the week number of the year on the left side before the days are shown?

  44. atikus
    April 9, 2010 @ 9:08 am

    I’ve used your code to implement events that are placed in a MySQL DB. Everything is fine, but when I output an event on a date then the prior date box () drops down. Is there anyway to avoid this?

    Thanks for your assistance!

  45. May 19, 2010 @ 3:07 am

    @Spielberg: and
    $headings = array(‘S’,'M’,'D’,'M’,'D’,'F’,'S’);
    to
    $headings = array(‘M’,'D’,'M’,'D’,'F’,'S’,'S’);

  46. russell
    May 19, 2010 @ 5:10 pm

    This is for the following people who want to add events from a Mysql database. I sure there is another way to do this but this is the way that I did it.

    Set up your table with the following fields
    id
    event
    startday
    startmonth
    startyear
    endday
    endmonth
    endyear

    The id field will be used to pull up the event when clicked on

    add the following code after the
    /** QUERY THE DATABASE FOR AN ENTRY FOR THIS DAY !! IF MATCHES FOUND, PRINT THEM !! **/

    $query = “SELECT * FROM events WHERE startmonth=$month AND startyear=$year AND startday = $list_day”;
    $results = mysql_query($query) or die (mysql_error());
    if (mysql_num_rows($results) > ’0′) {
    while($row = mysql_fetch_array($results)){
    extract($row);

    $calendar.= ‘‘.$event.’‘;

    //end while
    }
    //end num_row if
    } else { $calendar.= ‘ ’;}

    Also add the following css:

    div.calendar-text {
    color:#111;
    }
    div.calendar-text a {
    color: #111;
    text-decoration: none;
    }
    div.calendar-text a:hover {
    color: #333;
    text-decoration: underline;
    }

    The good part about this is it will not only add events that only happen on one but it will add events that span across several days!
    Hope this helps!

  47. russell
    May 19, 2010 @ 5:13 pm

    How to highlight the current day

    Change this code:
    for($list_day = 1; $list_day <= $days_in_month; $list_day++):
    29
    $calendar.= '’;
    30
    /* add in the day number */
    31
    $calendar.= ”.$list_day.”;

    To this:

    for($list_day = 1; $list_day <= $days_in_month; $list_day++):
    if($list_day == $today && $month == $nowmonth && $year == $nowyear) {
    $calendar.= '’;
    } else {
    $calendar.= ”;
    }
    /* add in the day number */
    $calendar.= ”.$list_day.”;

    And add the following CSS

    td.calendar-day-today {background: #f00;}

  48. May 20, 2010 @ 8:15 am

    @Russell: How do include the end dates into this function?

    I would like to highlight the days from the start to the finish date, not just highlight a single day. So i need to identify from the days in between as well. Can you do a piece that could do that? It would help alot. Thank you.

  49. May 20, 2010 @ 9:29 am

    @Sebastien: This what i have:

    $Sday = substr($row['start_date'],8,2);
    $Smonth = substr($row['start_date'],5,2);
    $Syear = substr($row['start_date'],0,4);
    $dateStart = $Syear.”/”.$Smonth.”/”.$Sday;
    $Eday = substr($row['end_date'],8,2);
    $Emonth = substr($row['end_date'],5,2);
    $Eyear = substr($row['end_date'],0,4);
    $dateEnd = $Eyear.”/”.$Emonth.”/”.$Eday;

    $query = “SELECT * FROM events WHERE `user`=’{$session->username}’ BETWEEN `start_date`=’{$dateStart}’ AND `finish_date`=’{$dateEnd}’”;

    And i get this in return:

    ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘=’2010/05/19′ AND `finish_date`=’2010/06/30” at line 1

  50. waspinator
    June 19, 2010 @ 8:22 am

    Is there a way to turn Saturdays and Sundays to class=”calendar-day-np” ?

    Thanks

  51. waspinator
    June 19, 2010 @ 10:07 am

    @waspinator:

    just add this change:

    /* keep going with days…. */
    for($list_day = 1; $list_day <= $days_in_month; $list_day++):
    if($running_day == 0 || $running_day == 6)
    $calendar.= '’;
    else
    $calendar.= ”;

  52. June 21, 2010 @ 1:08 am

    @waspinator: schizophrenic? :-)

  53. July 15, 2010 @ 7:46 pm

    @Adriaan: I love Google Calendar, too. But does it doesn’t degrade gracefully when Javascript is absent, at least in the embedded version. I personally hate relying on JS for functionality that is potentially critical on the end-user’s side. (@David – No offense to MooTools and JS in general! I use AJAX quite frequently, just not for core functionality.)

    Server-side is the way to go, and PHP is the best for that. Not to mention 3rd party integration (for adding events, etc) is a non-issue when you’ve got the control.

    @David: Nice work! I had the bulk of my own event calendar class built, but your day-counting, table-structuring awesomeness served as a great inspiration, and your CSS is serving perfectly until I can get sliced static pages from the powers that be. Keep on dev-ing.

  54. August 20, 2010 @ 10:02 am

    $year = date ('Y');
    $month_title = date ('F');
    $month_display = date ('n');
    /* sample usages */
    echo ''.$month_title.' '.$year.'';
    echo draw_calendar($month_display,$year);

    Add this to pull in current month and year!

    enjoy!

  55. August 24, 2010 @ 5:02 pm

    Hi David,

    Many thanks for the calendar code, I look forward to using it. I just noticed one minor quirk, where if the last day of the month falls on a saturday, it adds an empty table row to the end of the calendar month. Here’s my fix for that:


    /* finish the rest of the days in the week */
    if($days_in_this_week < 8 && $days_in_this_week !=1):
    for($x = 1; $x <= (8 - $days_in_this_week); $x++):
    $calendar.= ' ';
    endfor;
    endif;

    The bit in bold works for me. I hope others find it helpful as well.

    Best,

    -A.

  56. alan
    August 30, 2010 @ 11:41 am

    I David,

    Many thanks for the calendar code, I look forward to using it.I was wondering if is possible to transform the view of this MONTH calendar to a weekly one?

    thanks

Be Heard!

Share your thoughts with fellow developers of all skill levels! I want to hear from you!

Name*:
Email*:
Website:  
Wrap your code with <code> tags, f00!