Simple php calendar with any day offset

I am coding a quite huge calendar script for various works I have in progress.
The barebones of this calendar I have coded today represent a php function that returns a calendar into an html table of any month of any year (according to php limits) with any day offset.
This means your calendar could start on sunday, monday, tuesday and so on.
It’s just the beginning but you can customize it with styles and other funny things.

Let’s see the code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function calendar($year, $month, $day_offset = 0){ 
    $days = array("sunday","monday","tuesday","wednesday","thursday","friday","saturday");
    $months = array("january","february","march","april","may","june","july","august","september","october","november","december");
    $day_offset = $day_offset % 7;
    $start_day = gmmktime(0,0,0,$month,1,$year); 
    $start_day_number = date("w",$start_day);
    $days_in_month = date("t",$start_day);
    $final_html .= "<table>\n<tr><td colspan = \"7\">".$months[$month-1]." $year</td></tr>\n";
    for($x=0;$x<=6;$x++){
    	$final_html .= "<td>".$days[($x+$day_offset)%7]."</td>";
    }
    $final_html .= "</tr>\n";
    $blank_days = $start_day_number - $day_offset;
    if($blank_days<0){$blank_days = 7-abs($blank_days);}
    for($x=0;$x<$blank_days;$x++){
    	$final_html .= "<td>x</td>";
    }
    for($x=1;$x<=$days_in_month;$x++){
    	if(($x+$blank_days-1)%7==0){
    		$final_html .= "</tr>\n<tr>";
    	}
    	$final_html .= "<td>$x</td>";
    }
    while((($days_in_month+$blank_days)%7)!=0){
    	$final_html .= "<td>x</td>";
    	$days_in_month++;
    }
    $final_html .= "</tr>\n</table>";
	return($final_html);
}

Since it’s just the beginning the code is quite simple, but if you have any question or suggestion, just leave a comment.

How will you use this function?

If you want the March 2006 calendar starting on Sunday, just

1
echo calendar(2006,3);

and the result is

function calendar($year, $month, $day_offset = 0){
$days = array("sunday","monday","tuesday","wednesday","thursday","friday","saturday");
$months = array("january","february","march","april","may","june","july","august","september","october","november","december");
$day_offset = $day_offset % 7;
$start_day = gmmktime(0,0,0,$month,1,$year);
$start_day_number = date("w",$start_day);
$days_in_month = date("t",$start_day);
$final_html .= "
\n

\n”;
for($x=0;$x<=6;$x++){
$final_html .= "

“;
}
$final_html .= “

\n”;
$blank_days = $start_day_number – $day_offset;
if($blank_days<0){$blank_days = 7-abs($blank_days);}
for($x=0;$x<$blank_days;$x++){
$final_html .= "

“;
}
for($x=1;$x<=$days_in_month;$x++){
if(($x+$blank_days-1)%7==0){
$final_html .= "

\n

“;
}
$final_html .= “

“;
}
while((($days_in_month+$blank_days)%7)!=0){
$final_html .= “

“;
$days_in_month++;
}
$final_html .= “

\n

“.$months[$month-1].” $year
“.$days[($x+$day_offset)%7].”
x
$x x

“;
return($final_html);
}

echo calendar(2006,3);

?>

While if you want April 2006 starting from monday, just

1
echo calendar(2006,4,1);

and the result is

GRAHAM Sent me a code he modified to include cycling through months and years and converted it to div’s making it xhtml compliant.

Here it is

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Calender</title>
<style type="text/css">
ul.calender{
	background-color: #CCCCCC;
	margin: 0px;
	width: 560px;
	clear: both;
	float: left;
	border-top-width: 1px;
	border-top-style: solid;
	border-top-color: #F4F4F4;
	font-size: 10px;
	text-transform: uppercase;
	list-style-type: none;
	padding: 0px;
}
ul.calender li{
	margin: 0px;
	border-top: 1px solid #FFFFFF;
	border-bottom: 1px solid #999999;
	padding: 2px 0px 5px;
}
ul.calender2{
	background-color: #FFFFFF;
	margin: 0px;
	width: 100%;
	clear: both;
	float: left;
	font-size: 12px;
	list-style-type: none;
	padding: 0px;
	font-weight: bold;
}
ul.calender2 li{
	margin: 0px;
	padding: 2px 0px 5px;
}
.nav1{
	display: block;
	width: 80px;
	float: left;
	text-align: center;
}
.nav2{
	display: block;
	width: 400px;
	float: left;
	text-align: center;
}
</style>
</head>
<body>
<?php
function calendar($year, $month, $day_offset = 0){ 
    $days = array("sunday","monday","tuesday","wednesday","thursday","friday","saturday");
    $months = array("january","february","march","april","may","june","july","august","september","october","november","december");
    $day_offset = $day_offset % 7;
    $start_day = gmmktime(0,0,0,$month,1,$year); 
    $start_day_number = date("w",$start_day);
    $days_in_month = date("t",$start_day);
 
	$previous_month = ($month-1);
	$previous_year = $year;
	if($previous_month == 0){
	  $previous_month = '12';
	  $previous_year = ($year-1);
	} 
 
	$next_month = ($month+1);
	$next_year = $year;
	if($next_month == '13'){
	  $next_month = '1';
	  $next_year = ($year+1);
	} 
 
    $final_html .= "<ul class=\"calender\"><li><span class=\"nav1\"><a href=\"calender.php?y=".$previous_year."&amp;m=".$previous_month."\">Back</a></span><span class=\"nav2\">".$months[$month-1]." $year</span><span class=\"nav1\"><a href=\"calender.php?y=".$next_year."&amp;m=".$next_month."\">Next</a></span></li>\n";
    $final_html .= "<li>";
	for($x=0;$x<=6;$x++){
        $final_html .= "<span class=\"nav1\">".$days[($x+$day_offset)%7]."</span>";
    }
    $final_html .= "</li>\n";
 
	$final_html .= "</ul><ul class=\"calender2\"><li>\n"; 
 
 
    $blank_days = $start_day_number - $day_offset;
    if($blank_days<0){$blank_days = 7-abs($blank_days);}
    for($x=0;$x<$blank_days;$x++){
        $final_html .= "<span class=\"nav1\">&nbsp;</span>";
    }
    for($x=1;$x<=$days_in_month;$x++){
        if(($x+$blank_days-1)%7==0){
            $final_html .= "</li>\n<li>";
        }
        $final_html .= "<span class=\"nav1\"><a href=\"javascript:;\">$x</a></span>";
    }
    while((($days_in_month+$blank_days)%7)!=0){
        $final_html .= "<span class=\"nav1\">&nbsp;</span>";
        $days_in_month++;
    }
    $final_html .= "</li>\n</ul>";
    return($final_html);
} 
 
if(isset($_GET['y'])){
	$y = $_GET['y'];
} else {
	$y = date("Y");
}
if(isset($_GET['m'])){
	$m = $_GET['m'];
} else {
	$m = date("m");
}
echo calendar($y,$m); 
?>
</body>
</html>
Rate this post: 1 Star2 Stars3 Stars4 Stars5 Stars (12 votes, average: 4.08 out of 5)
Loading ... Loading ...
Be my fan on Facebook and follow me on Twitter! Exclusive content for my Facebook fans and Twitter followers

This post has 25 comments

  1. Henry

    on July 6, 2006 at 10:52 am

    Please check line8 & line9
    You open tag without any

    ps. it’s a very good & simple function i’ve looking for! thanks a lot!

  2. Juan

    on July 11, 2006 at 10:12 pm

    Love this function :) Keep up the good work!

  3. Andrew

    on July 13, 2006 at 6:32 pm

    Hi, this is a really neat function, but I don’t think it works quite right–try putting in July

    echo calendar(2006,7,1);

    and you’ll notice that it is one day of the week behind . . .

  4. Emanuele Feronato

    on July 14, 2006 at 1:53 am

    Hi Andrew, I tried but I got a correct result, with weekaday starting on monday and 1st on saturday

  5. Graham

    on July 18, 2006 at 1:18 pm

    Hello, thankyou for the nice script, very simple to use. I’ve added some more functionality, back and next buttons to cycle through months/years. Plus i’ve converted it to XHTML compliant code using div’s and ul’s. Thought i’d send you a copy – hope you like.

    Edited by Emanuele Feronato: Graham’s update is here.
    Thank you very much.

  6. Andrew

    on July 18, 2006 at 8:02 pm

    Hi, the problem (for me, writing from the States) was the function gmmktime() in line 5–using mktime() makes the dates line up over here . . . .

    Thanks again for posting the script.

  7. Joost Canters

    on September 5, 2006 at 12:27 pm

    Really nice one mister Feronato. This was the kind of less = more calendar script i was looking for.

  8. Juan

    on October 10, 2006 at 2:38 am

    Hi, i have a problem with February, this calendar say that the month has 31 days :s and that afect other months like oct, it say has a 30 days how can i fix that?

  9. Mike

    on October 22, 2006 at 3:25 am

    DATE FIX Ok, on line 5 you must change $start_day = gmmktime(0,0,0,$month,1,$year);
    to this $start_day = mktime(0,0,0,$month, 1, $year); this will fix the days in the month issue. and show the correct date. http://marylandwebsites.net

  10. swahalla

    on November 9, 2006 at 11:20 pm

    great, this saved me a couple of hours work =)

  11. niabi

    on December 20, 2006 at 8:07 am

    Too bad the CSS is broken on all other browsers but IE :(

  12. Marcos J Pinto

    on May 6, 2007 at 5:51 pm

    Thanks for this code.
    You’ve saved me a lot of hours of work here too.
    Working fine here (Brazil) with mktime instead of gmmktime

  13. augusto

    on August 20, 2007 at 9:50 pm

    Excellent!

    I prefer the emanuele version —with minor adjustements— is nice, simple & unbloatted. Tables are great for tabular data even in XHTML, so convert the table in div’s make no sense.

  14. Rob

    on February 7, 2008 at 10:33 pm

    Excuses for kicking… I googled this page up.

    Got something to report:

    line 12: $final_html .= “\n”;

    fix that into: $final_html .= “\n”;

    cause on line 16 u start with some ‘s and there is no to start it with.

    bye, Rob.

  15. agbagbara

    on April 3, 2008 at 1:20 am

    Hi.

    Best ever, honestly, saved me hours, Had only one problem, the gmmktime function seems to return a different result so had to use mktime, maybe because I am in australia or maybe because I am on my local machine.

    Any way great stuff, thanks a lot.

  16. Ruben De Smet

    on June 11, 2008 at 4:52 pm

    This is what I need!

    But add:

    if($leap){
    $day_offset–;
    }

    between line 11 and 12 to add Leap functionality.

    Ruben

  17. Ruben De Smet

    on June 11, 2008 at 4:53 pm

    Oops…
    I forget to add
    $leap=date(“L”);
    to my code…

    Ruben

  18. Sakke

    on June 23, 2008 at 12:56 pm

    Excellent; just what I was looking for. Thank you :)

  19. cocoy

    on June 24, 2008 at 7:05 pm

    your a genius mister feronato

  20. Chris Pos

    on November 10, 2008 at 10:01 pm

    Just comes up with T_String error after $days array your line 2

  21. Graham Brown

    on April 3, 2009 at 12:43 am

    Change:
    ul.calendar2
    width:560px

    to fix CSS problems.

    Checked in Safari and Firefox.

  22. Graham Brown

    on April 7, 2009 at 1:59 am

    Also, watch out for the spelling of “calendar”.

    In the code it’s spelt “calender”.

    If you name you file with the correct spelling the link to the new month won’t work.

  23. Kay

    on October 21, 2009 at 1:36 pm

    Thanks for this, great script!

    On Graham’s version I had an error though, I just removed a dot from line 80:

    From – $final_html .= “<ul …
    To – $final_html = "<ul …

    Also just added width 560px as the person above has mentioned.

  24. cv

    on July 3, 2010 at 11:34 am

    Hello

    Is it possible to easily view the days of the previous and next month instead of x?

  25. Vincent

    on May 18, 2011 at 8:56 pm

    I needed a booking calendar for my b&b client.

    Ended up going with http://bookingbaboon.com instead of your script.

    Thanks anyways
    Vincent