Page 1 of 1

Total weeks in a month

Posted: Thu Oct 05, 2006 1:59 pm
by Luke
I got this little bit of code off of php.net's user contributed notes, but it doesn't work correctly... I can't figure out what's wrong with it... it's supposed to calculate the amount of weeks in a given month.

Code: Select all

public function totalWeeks(){
// $this->date is just a timestamp
		$first_day_of_month = strtotime("-" . (date("d", $this->date)-1) . " days", $this->date);
		$last_day_of_month = strtotime("+" . (date("t", $first_day_of_month)-1) . " days", $first_day_of_month);
		
		$first_week_no = date("W", $first_day_of_month);
		$last_week_no = date("W", $last_day_of_month);
		
		if($last_week_no < $first_week_no) $last_week_no=date("W", strtotime("-1 week",$last_week_no)) + 1;
		$weeks_of_month = $last_week_no - $first_week_no + 1;
		return $weeks_of_month;
		
	}
Is there a better way to do this altogether?

Posted: Thu Oct 05, 2006 2:49 pm
by Luke
Here... I posted it on my site so you guys can better see what I'm talking about...
http://mc2design.info/MC2_Calendar.php? ... &year=2007
It seems like any month which has it's first day as the first sunday gets alloted 1 more week than necessary... I don't know why. I didn't get much sleep last night, and I'm sure it wouldn't be that hard to figure out, but I'm exhausted... any help is appreciated. Thanks! :)

Posted: Thu Oct 05, 2006 4:26 pm
by Luke
I decided to forget about calculating the amount of weeks before-hand and just hacked away until I got it to work... look how ugly this is though...

Code: Select all

public function draw($events=array()){

		$day_num = false;
		$output =  "<table border='1' cellspacing='0' cellpadding='0'>\n";
		$output .= " <tr>\n  <td colspan='" . count($this->week) . "'>" . $this->month->fullName() . " - " . $this->month->year() . "</td>\n </tr>\n <tr>\n";
		foreach($this->week as $day){
			$output .= "  <td>" . $day . "</td>\n";
		}
		$output .= "</tr>";
		$break_outer = false;
		$break_inner = false;
		for($i = 1; $i <= 7; $i++){
			if($break_outer) break;
			$output .= "<tr>";
			for($j = 0; $j < 7; $j++){
				// This tells the loop when to print the first of the month
				if(($i == 1) && ($this->week[$j] == $this->month->startDay())){
					$day_num = 1;
				}
				// If we run our of days...
				if($day_num > $this->month->totalDays()){
					// Reset day
					$day_num = 0;
					// Break outer loop
					$break_outer = true;
					// Print the remaining days of the week with blank cells
					if($j){
						$days_left = 7 - $j;
						for($k=1;$k<=$days_left;$k++) $output .= "  <td>&nbsp;</td>\n";
					}
					// Break inner loop
					break;
				}
				$day_num = $day_num ? $day_num : '&nbsp;';
				$output .= "  <td>" . $day_num . "</td>\n";
				$day_num++;
			}
			$output .= "</tr>";
		}
		$output .= " \n</table>";
		print $output;
		
	}

Posted: Thu Oct 05, 2006 4:36 pm
by patrikG
Why so complicated? I'd refactor it like this

Code: Select all

echo "Number of weeks in a given months? 4";
:wink:

Posted: Thu Oct 05, 2006 4:39 pm
by Luke
how would that help?

Posted: Thu Oct 05, 2006 4:40 pm
by wtf

Posted: Thu Oct 05, 2006 4:41 pm
by Luke
read my first post please. :) :P

Posted: Thu Oct 05, 2006 4:53 pm
by patrikG
The Ninja Space Goat wrote:how would that help?
It cheers you up.

But seriously: I've used the same script some time back (from the manual) and hacked around. The result won't win any design-contests, but it did what it had to then.

Code: Select all

//wrap this into some class
	function set_calendar_grid(){
		$days				=	$this->get_month_days();
		$this->month_name	=	$days["month"];

		for($i=$days["first_day"];$i<$days["days_in_month"]+$days["first_day"];$i++){
			$weekday	=	((int)$i%7);

			$this->grid[$i]	= array("day"=>$this->weekday[$weekday]);
			$this->grid[$i]["weekday"]		=	$weekday;
			$this->grid[$i]["weeknumber"]	=	date("W",mktime(0,0,0,$this->month,$i,$this->year));

			if($i==$days["first_day"]){
				$this->grid[$i]["first_day"]=true;
				$this->grid[$i]["css_class"]="firstday";
				if($weekday==6 || $weekday==0){
					$this->grid[$i]["css_class"].="weekend";
				}
			}
			elseif($weekday==6 || $weekday==0){
				$this->grid[$i]["css_class"].="weekend";
			}
			else{
				$this->grid[$i]["css_class"]="normal";
			}
			if(date("d")==$i){
				$this->grid[$i]["today"]=true;
			}

		}
		$this->offset	=	$days["first_day"]-1;
	}


	function get_month_days(){
		$return["days_in_month"]	=	date("t",mktime(0,0,0,$this->month,1,$this->year));
		$return["first_day"]		=	(date("w",mktime(0,0,0,$this->month,1,$this->year))) ? date("w",mktime(0,0,0,$this->month,1,$this->year)) : 7;
		$return["month"]			=	date("F",mktime(0,0,0,$this->month,1,$this->year));
		return $return;
	}
and the calling script/page

Code: Select all

require_once(ROOT_PATH."classes/class_calendar.inc.php");
$calendar	=	&new calendar(filter::sanitise_number($_GET["m"]),filter::sanitise_number($_GET["y"]));
$calendar->set_calendar_grid();
$calendar->set_url_parameters();
?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
	<title>Calendar</title>
<style type="text/css" media="screen">
@import "css/main.css";
@import "css/calendar_grey.css";
</style>
<!-- We hates IE, we hates it. Yes, precious. We hates it. -->
<!--[if IE]>
<link
href="css/mainIE.css"
rel="stylesheet"
type="text/css"
media="screen">
<link
href="css/calendar.css"
rel="stylesheet"
type="text/css"
media="screen">
<![endif]-->
</head>
<body>
<?php include("templates/header.html");?>
		<table width="100%" height="100%" class="calendar" summary="view of calendar">
			<tr class="navigation">
				<td colspan="8"><span><a href="<?php echo $_SERVER["PHP_SELF"]."?".$calendar->url["month_previous"]?>"><img src="graphix/arrow_left.gif" alt="previous month" width="12" height="11" border="0"></a> <?php echo $calendar->month_name." ".$calendar->year;?> <a href="<?php echo $_SERVER["PHP_SELF"]."?".$calendar->url["month_next"]?>"><img src="graphix/arrow_right.gif" alt="next month" width="12" height="13" border="0"></a></span></td>
			</tr>
			<tr>
				<th class="weeknumber">Week</th>
				<th>Mon</th>
				<th>Tue</th>
				<th>Wed</th>
				<th>Thu</th>
				<th>Fri</th>
				<th>Sat</th>
				<th>Sun</th>
			</tr>
			<tr>
<?php
		for($i=1;$i<=35;$i++){
			if($i==1 || $i==8 || $i==15 || $i==22 || $i==29){
				echo "<td class='weeknumber'>".date("W",mktime(0,0,0,$calendar->month,$i,$calendar->year))."</td>";
			}
			if($calendar->grid[$i]){
				echo '<td id="day'.$i.'" class="'.$calendar->grid[$i]["css_class"].'"><span class="day">'.($i-$calendar->offset).'</span></td>';
			}
			else{
				echo '<td class="blank">&nbsp;</td>';
			}
			if(!($i%7)){
				echo "</tr><tr>";
			}
		}

?>
		  </tr>
		</table>
	</div>
</body>
</html>
edit: If you use it and refactor it: please post your version.

Posted: Thu Oct 05, 2006 5:04 pm
by Luke
Aww... I already rewrote it...

Code: Select all

public function draw(){
	
		$output =  "<table border='1' cellspacing='0' cellpadding='0'>\n";
		$output .= " <tr>\n  <td colspan='" . count($this->week) . "'>" . $this->month->fullName() . " - " . $this->month->year() . "</td>\n </tr>\n <tr>\n";
		foreach($this->week as $day){
			$output .= "  <td>" . $day . "</td>\n";
		}
		$output .= "</tr><tr>\n";
		
		$first_day = date('w', $this->month->date());
		for ($i=0; $i<$first_day; $i++){
			$output .= "<td>&nbsp;</td>\n";
		}
		
		for ($list_day=1; $list_day <= $this->month->totalDays(); $list_day++){
			$output .= "<td width='100' height='80'>" . $list_day . "</td>\n";
			if ($first_day == 6){
				$output .= "</tr>\n";
				$output .= "<tr>\n";
				$first_day = -1;
			}
			$first_day++;
			$days_left = ($first_day) ? 7 - $first_day : 0;
			// Print out the week's remaining day's cells
			if($list_day == $this->month->totalDays()){
				for($i = 1; $i <= $days_left; $i++){
					$output .= "<td width='100' height='80'>&nbsp;</td>\n";
				}
			}
		}
		
		$output .= "</tr>\n";
		$output .= "</table>\n";
		echo $output;
		
	}

Just a piece of code I have used.

Posted: Fri Oct 06, 2006 3:15 pm
by churt
You might also be able to use some of this. Let me know what you think.

Code: Select all

function mycalendar($tstamp, $nm, $pm, $ny, $py){
    echo "<form name='calendar' action='".$PHP_SELF."' method=post>";

    //Init variables
    if (!$tstamp) $tstamp=date('m/d/Y', mktime());
    $bgcolor='white';

    //Navigation
    if ($nm) $tstamp=date('m/d/Y', strtotime("+1 month", strtotime($tstamp)));
    if ($pm) $tstamp=date('m/d/Y', strtotime("-1 month", strtotime($tstamp)));
    if ($ny) $tstamp=date('m/d/Y', strtotime("+1 year", strtotime($tstamp)));
    if ($py) $tstamp=date('m/d/Y', strtotime("-1 year", strtotime($tstamp)));

    //First day of month
    $fday=date("w", strtotime("1 ".date("F", strtotime($tstamp))."", strtotime($tstamp)));

    //Total days of month
    $tdays=(date('d', strtotime("-1 day", strtotime("1 ".date("F", strtotime("+1 month", strtotime($tstamp)))))));

    //Start calendar
    echo "<table border=1 cellspacing='0' cellpadding='0'><tr><td align=center><table>";
   
    //Navigation Controls
    echo "<tr><td><input type=submit name=py value='<<' title='Previous Year'></td>
    <td align=center>Year</td><td><input type=submit name=ny value='>>' title='Next Year'></td></tr>";
    echo "<tr><td><input type=submit name=pm value='<<' title='Previous Month'></td><td align=center>Month</td>
    <td><input type=submit name=nm value='>>' title='Next       Month'></td></tr></table></td></tr>";
    echo "<tr><td align=center>".date("F", strtotime($tstamp))." &nbsp ".date("Y", strtotime($tstamp))."</td></tr>";

    //Day of week lables
    echo "<tr><td><table style='border: 1px solid'><tr>";
    for($h=0; $h<7; $h++){ echo "<td bgcolor=$bgcolor>".date("D", strtotime("+$h day", strtotime("last sunday", mktime())))."</td>"; }
    echo "</tr>";

    //Days of month
    for($i=1; $i<=$tdays; $i++){
        echo "<tr>";
        //Break into weeks
        for($j=0; $j<7; $j++){
            if ((!$dy and $j<$fday) or $i>$tdays){
               $dy='';
            }else{
               $dy="<input type=submit name=sdate value='$i' style='cursor: pointer; background-color: $bgcolor; text-align: left; border-style: none; font-size: 9'>";
            }
            echo "<td width=80 height=80 bgcolor=$bgcolor valign=top>$dy</td>";
            if ($dy) $i++;
        }
        echo "<tr>";
        $i--;
   }
   echo "</table><input type=hidden name=tstamp value='$tstamp'>";
   echo "</form>";
}//End Function

//Call Calendar and echo date if selected
mycalendar($tstamp, $nm, $pm, $ny, $py);
if ($sdate) $sdate=date('m', strtotime($tstamp)).'/'.$sdate.'/'.date('Y', strtotime($tstamp));
echo $sdate;