some calendar logic help

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

some calendar logic help

Post by s.dot »

So I'm making a rolling calendar.. it will display the current month plus the next two months. What I have right now is working (since it is march), but if the current month is november or december, it won't display into the following year because of how i'm doing my for() loop.

Here's the complete script

Code: Select all

<?php
 
//array of months
$months = array(
    'January' => 1,
    'February' => 2,
    'March' => 3,
    'April' => 4,
    'May' => 5,
    'June' => 6,
    'July' => 7,
    'August' => 8,
    'September' => 9,
    'October' => 10,
    'November' => 11,
    'December' => 12
);
 
$monthsF = array_flip($months);
 
//is this a leap year?
$leapYear = ((date('Y') % 4) == 0);
 
//current month and year
$currentMonth = date('n');
$currentYear = date('Y');
 
//number of days in each month
$monthDays = array(
    1 => range(1, 31),
    2 => $leapYear ? range (1, 29) : range(1, 28),
    3 => range(1, 31),
    4 => range(1, 30),
    5 => range(1, 31),
    6 => range(1, 30),
    7 => range(1, 31),
    8 => range(1, 31),
    9 => range(1, 30),
    10 => range(1, 31),
    11 => range(1, 30),
    12 => range(1, 31)
);
 
for ($month = $currentMonth; $month < $currentMonth + 3 ; $month++)
{
    //what day does the first of the month fall on?
    $startDayOfWeek = date('w', mktime(0, 0, 0, $month, 1, $currentYear));
    
    //start the table
    echo '<table cellspacing="0" cellpadding="2" border="0" style="border: solid 1px #000;">
        <tr>
            <td colspan="7" align="center" style="border-bottom: solid 1px #000;">' . $monthsF[$month] . '</td>
        </tr>
        <tr>
            <td>Sun</td>
            <td>Mon</td>
            <td>Tue</td>
            <td>Wed</td>
            <td>Thu</td>
            <td>Fri</td>
            <td>Sat</td>
        </tr>';
    
        //show blank table cells till first day of month occurs
        for ($i = 0; $i < $startDayOfWeek; $i++)
        {
            echo '<td>&nbsp;</td>';
        }
        
        //start the iteration at the number of days till the first day of the month occurs
        $it = $startDayOfWeek;
    
        //loop through the month's worth of days
        foreach ($monthDays[$month] AS $day)
        {
            if ($it == 7)
            {
                echo '</tr><tr>';
                $it = 0;
            }
        
            echo '<td align="center">' . $day . '</td>';
        
            $it++;
        }
 
    //end the table
    echo '</table><br />';
}
And here's the part that's giving me problems:

Code: Select all

for ($month = $currentMonth; $month < $currentMonth + 3 ; $month++)
$currentMonth + 3 will go over 12.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: some calendar logic help

Post by John Cartwright »

hint: use timestamps ;)
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Re: some calendar logic help

Post by s.dot »

I have always found that calculating days with timestamps is pretty ugly =| plus working in daylight saving time gets messy

Here's my hack.. that works, but damn it feels ugly.

Code: Select all

<?php
 
//array of months
$months = array(
    'January' => 1,
    'February' => 2,
    'March' => 3,
    'April' => 4,
    'May' => 5,
    'June' => 6,
    'July' => 7,
    'August' => 8,
    'September' => 9,
    'October' => 10,
    'November' => 11,
    'December' => 12
);
 
$monthsF = array_flip($months);
 
//is this a leap year?
$leapYear = ((date('Y') % 4) == 0);
 
//number of days in each month
$monthDays = array(
    1 => range(1, 31),
    2 => $leapYear ? range (1, 29) : range(1, 28),
    3 => range(1, 31),
    4 => range(1, 30),
    5 => range(1, 31),
    6 => range(1, 30),
    7 => range(1, 31),
    8 => range(1, 31),
    9 => range(1, 30),
    10 => range(1, 31),
    11 => range(1, 30),
    12 => range(1, 31)
);
 
//current month and year
//$currentMonth = date('n');
$currentMonth = 12;
$currentYear = date('Y');
 
 
for ($month = $currentMonth; $month < $currentMonth + 3; $month++)
{
    $rMonth = $month;
    
    if ($rMonth == 13)
    {
        $currentYear = $currentYear + 1;
        
        //is this a leap year?
        $leapYear = (($currentYear % 4) == 0);
 
        //number of days in each month
        $monthDays = array(
            1 => range(1, 31),
            2 => $leapYear ? range (1, 29) : range(1, 28),
            3 => range(1, 31),
            4 => range(1, 30),
            5 => range(1, 31),
            6 => range(1, 30),
            7 => range(1, 31),
            8 => range(1, 31),
            9 => range(1, 30),
            10 => range(1, 31),
            11 => range(1, 30),
            12 => range(1, 31)
        );
    }
    if ($rMonth == 13)
    {
        $rMonth = 1;
    } elseif ($month == 14)
    {
        $rMonth = 2;
    }
    
    //what day does the first of the month fall on?
    $startDayOfWeek = date('w', mktime(0, 0, 0, $rMonth, 1, $currentYear));
    
    //start the table
    echo '<table cellspacing="0" cellpadding="2" border="0" style="border: solid 1px #000;">
        <tr>
            <td colspan="7" align="center" style="border-bottom: solid 1px #000;">' . $monthsF[$rMonth] . ', ' . $currentYear . '</td>
        </tr>
        <tr>
            <td>Sun</td>
            <td>Mon</td>
            <td>Tue</td>
            <td>Wed</td>
            <td>Thu</td>
            <td>Fri</td>
            <td>Sat</td>
        </tr>';
    
        //show blank table cells till first day of month occurs
        for ($i = 0; $i < $startDayOfWeek; $i++)
        {
            echo '<td>&nbsp;</td>';
        }
        
        //start the iteration at the number of days till the first day of the month occurs
        $it = $startDayOfWeek;
    
        //loop through the month's worth of days
        foreach ($monthDays[$rMonth] AS $day)
        {
            if ($it == 7)
            {
                echo '</tr><tr>';
                $it = 0;
            }
        
            echo '<td align="center">' . $day . '</td>';
        
            $it++;
        }
 
    //end the table
    echo '</table><br />';
}
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: some calendar logic help

Post by John Cartwright »

I was thinking something more like:

Code: Select all

$secondsInDay = 60*60*24;
$daysInMonth = date('t');
for ($x = time(); $x <= strtotime('+3 months'); $x += ($secondsInDay * $daysInMonth)) {
   $daysInMonth = date('t', $x);
   echo date('m-Y', $x) .'<br>';
   //03-2008
   //04-2008
   //05-2008   
   //06-2008  
}
 
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Re: some calendar logic help

Post by s.dot »

That is much more elegant. Thanks.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: some calendar logic help

Post by Christopher »

Code: Select all

 
function month_next(&$month) {
     if ($month < 12) {
          ++$month;
     } else {
          $month = 1;
     }
     return $month;     // in case you need it
}
 
$month = $currentMonth;
for ($i=0; $i<3 ; ++$i) {
     // your code here
     month_next($month);
}
You would be much better off with a Calendar object that would do this <span style='color:blue' title='I&#39;m naughty, are you naughty?'>smurf</span>.
(#10850)
Post Reply