...

"Moving" calendar

bacterozoid
08-09-2008, 12:29 PM
This program will display a calendar that "moves". Typical calendars display the date by month. This was not useful for me as I often want to see what's in the coming weeks. A monthly calendar does not allow for this at the end of the month and I don't want to display multiple months.

So this solution displays the current week, as well as x previous weeks, and y upcoming weeks. You choose the numbers. I don't have it running on a public server, but you can copy the entire text of the provided code into a PHP file and run it.

createCalendar($previousWeeks, $upcomingWeeks)

It basically produces this type of output, where this calendar was generated on the 9th.

Calendar
S M T W T F S
27 28 29 30 31 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

The code is a bit lengthy, but it's split up into several functions and I've tried to make as much sense with comments and names as I can. I've tried to make it 100% generalized, but I haven't tested ALL of the corner cases. Hope someone can use this!

Obviously you can style this and change the display as much as you want, but the core of it is there. Feel free to PM me or post here if you have questions...or take the code and modify it. It's free for use.


<?PHP

CreateCalendar(1, 3);

/* Creates a calendar and places events on it. All date elements are 1-indexed.
It should theoretically work for infinite days into the future and all the way
back to to year 0 or 1. */
function createCalendar($previousWeeks, $upcomingWeeks)
{
$WEEKS_TOTAL = $previousWeeks + $upcomingWeeks + 1;
$DAYS_IN_WEEK = 7;
$DAY_OF_YEAR = date("z") + 1; // Used once but here because it makes more sense when it has a name
$FIRST_DAY_OFFSET = date("w") + ($DAYS_IN_WEEK * $previousWeeks) + 1; // Used once but here because it makes more sense when it has a name

$currentYear = date("Y"); // Current year on the calendar
$currentMonth = "";
$currentDayOfYear = $DAY_OF_YEAR - $FIRST_DAY_OFFSET + 1; // Numerical day of the year, where current means the current cell, not today.
$lastDayOfYear = getDaysInYear($currentYear);
$isLeapYear = isLeapYear($currentYear);

echo "<table>
<tr>
<td colspan='7'>
Calendar
</td>
</tr>
<tr>
<td>S</td><td>M</td><td>T</td><td>W</td><td>T</td><td>F</td><td>S</td>
</tr>";

for($i = 0; $i < ($WEEKS_TOTAL * $DAYS_IN_WEEK); $i++)
{
if($i % $DAYS_IN_WEEK == 0)
{
echo "<tr>";
}

// Meaning that we are displaying a year in the future on the calendar
if($currentDayOfYear > $lastDayOfYear)
{
$currentDayOfYear = 1; // Start the day counter over
$currentYear += 1; // Go to the next year
$lastDayOfYear = getDaysInYear($currentYear); // Learn the number of days in this year
$isLeapYear = isLeapYear($currentYear); // Is the new year a leap year?
}
// Meaning that we are displaying a previous year on the calendar
else if($currentDayOfYear < 1)
{
$adjustedDateInfo = getYearAndDayFromNegativeDayOfYear($currentDayOfYear, $currentYear);
$currentYear = $adjustedDateInfo[0]; // Get the year the calendar starts at
$currentDayOfYear = $adjustedDateInfo[1]; // Get the current day of the year in the past
$isLeapYear = isLeapYear($currentYear); // Is that year a leap year?
$lastDayOfYear = getDaysInYear($currentYear); // Learn the number of days in this year
}

$dateInfo = getDateInfoFromDayOfYear($currentDayOfYear, $isLeapYear);
$currentMonth = getMonthFromIndex($dateInfo[1]);

// DETAILS
// $currentMonth Abbreviated text representation of the current month
// $dateInfo[0] The day of the current month, no leading 0
// $dateInfo[1] The index of the current month (1-indexed)
// $currentYear Full representation of the current year
// $currentDayOfYear 1-indexed number representing the current day of the year (1-365 or 366)

echo "<td>$dateInfo[0]</td>";
$currentDayOfYear++;

if( ($i + 1) % $DAYS_IN_WEEK == 0)
{
echo "</tr>";
}
}

echo "</table>";
}

/* createCalendar helper function to get the date info from a day of the year */
function getDateInfoFromDayOfYear($dayOfYear, $isLeapYear)
{
$DAYS_IN_MONTHS = array(31,28,31,30,31,30,31,31,30,31,30,31);
if($isLeapYear)
$DAYS_IN_MONTHS[1] = 29;

$day = $dayOfYear; // Will end up being the day of the month we find
$month = 0; // Zero-indexed for now, adjusted in the return statement

while($day > $DAYS_IN_MONTHS[$month])
{
$day -= $DAYS_IN_MONTHS[$month];
$month++;
}

return array($day, ($month + 1)); // Plus 1 to make all the date stuff 1-indexed
}

/* Need this function to check if a year is a leap year because of the forward/backward capability of the calendar. */
function isLeapYear($year){
if(($year % 400) == 0)
{
return true;
}
else if(($year % 100) == 0)
{
return false;
}
else if(($year % 4) == 0)
{
return true;
}
else
{
return false;
}
}

// Gets the number of days in a given year
function getDaysInYear($year)
{
return (isLeapYear($year) ? 366 : 365 );
}

// Gets a month text based on an index
function getMonthFromIndex($index)
{
$months = array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
return $months[$index - 1]; // Minus 1 to make all the date stuff 1-indexed
}

//Finds out how many years in the past a negative day year is
function getYearAndDayFromNegativeDayOfYear($day, $currentYear)
{
$yearsBack = 1;
$dayOfPreviousYear = abs($day);
$daysInLoopYear = getDaysInYear($currentYear - $yearsBack);
while($dayOfPreviousYear > $daysInLoopYear)
{
$dayOfPreviousYear -= $daysInLoopYear;
$yearsBack++;
}

$year = $currentYear - $yearsBack;

return array($year, $daysInLoopYear - $dayOfPreviousYear + 0);
}

?>

Len Whistler
08-15-2008, 06:56 AM
I just installed your script in my code snippet folder. Very nice.




------

bacterozoid
08-15-2008, 12:00 PM
I appreciate the comment and I'm glad you like it! :) Use and modify however you wish.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum