Okay, so I've done the same thing with recurring events, and I still have the year. Losing the year really limits what you can and can't do with the dates. Plus, what if they want it to recur the first tuesday of every month? Since the 3rd is not always the same day (Tues, Wed, Sat, Sun) then you have to know which day it was to begin with 😉
I set up recurring events in a database so that the date of the event was a YYYYMMDD timestamp, and then in another field I put an integer denoting which type of recursion they wanted:
0 :: No recursion
5 :: Daily
4 :: Weekly
3 :: Bi-Weekly (Fortnightly)
2 :: Monthly
1 :: Annually
Now, based on that, I can grab what I need from the database based upon the start and end dates, and populate a month with each element. Now PHP is used to calculate which day it recurs upon, and populates an array of dates that there is an event.
So there are other ways to deal with recurring elements. Removing the year is not always the best of ideas. I guess if you wanted to, you could do something like:
<?php
$begin_date = '0915';
$end_date = '0202';
if(substr($begin_date, 0, 2) > substr($end_date, 0, 2))
{
$begin_year = date('Y');
$end_year = $begin_year+1;
}
else
{
$begin_year = $end_year = date('Y');
}
$begin = strtotime($begin_year.$begin_date);
$end = strtotime($end_year.$end_date);
$now = strtotime(date('Ymd'));
if($begin <= $now && $end >= $now)
{
// Date is within beginning and ending time
echo 'Within Limits';
}
else
{
// Date is not within beginning and ending time
echo 'Outside Limits';
}
But still, if you had the years, you wouldn't have to pull every item out of the database, you could easily make do with it in the database 😉
Here's an example of the query to get all my recurring items that are happening based upon the user-input date:
SELECT ci.`id`, ci.`domain_id`, ci.`event_name` AS `event`, ci.`event_date`, ci.`description`,
ci.`end_date`, ci.`recurring`, ci.`event_time`, ci.`all_day_event`
FROM `calendar_item` ci
WHERE (
(
ci.`recurring` = 0
AND ci.`event_date` >= '{$this->_year}-{$this->_month}-01'
AND ci.`event_date` <= '{$this->_year}-{$this->_month}-{$this->_totalDays}'
)
OR
(
ci.`recurring` > 1
AND ci.`end_date` >= '{$this->_year}-{$this->_month}-01'
AND ci.`event_date` <= '{$this->_year}-{$this->_month}-{$this->_totalDays}'
)
OR
(
ci.`recurring` = 1
AND MONTH(ci.`event_date`) = MONTH('{$this->_year}-{$this->_month}-01')
AND YEAR(ci.`end_date`) >= '{$this->_year}'
)
OR
(
ci.`recurring` > 0
AND ci.`event_date` <= '{$this->_year}-{$this->_month}-{$this->_totalDays}'
AND ci.`end_date` = '0000-00-00'
)
)
Now, here's how I do the recursion of each item (if needed):
/**
* @desc Sift through the result-set and generate the array for all recurring and non-recurring items
* @access protected
* @method siftRecurringItems
* @param MySQL Result Resource $result
* @return null
*/
protected function siftRecurringItems($result, $var='_events')
{
while($row = mysql_fetch_assoc($result))
{
$obj = new Calendar_Item_Event;
$obj->setID($row['id'])
->setAllDay($row['all_day_event'])
->setTitle($row['event'])
->setTime($row['event_time'])
->setDescription($row['description'])
->generateUrl();
list($evtYear, $evtMonth, $evtDay) = explode('-', $row['event_date']);
list($endYear, $endMonth, $endDay) = explode('-', $row['end_date']);
/**
* Single, non-recurring event
*/
if($row['recurring'] == 0)
$this->{$var}[intval($evtDay)][] = $obj;
else
{
$lastDay = ($endMonth == $this->_month && $endYear == $this->_year && $endDay != '00') ? intval($endDay) : $this->_totalDays;
/**
* Daily Events
*/
if($row['recurring'] == 5)
{
$start = ($evtMonth == $this->_month && $evtYear == $this->_year) ? intval($evtDay) : 1;
for($i=$start; $i<=$lastDay; $i++)
{
$this->{$var}[$i][] = $obj;
}
}
/**
* Weekly Events
*/
elseif($row['recurring'] == 4)
{
$day = date('w', strtotime($row['event_date']));
$firstDay = getFirstDay($this->_month, $day, $this->_year);
if($this->_month == $evtMonth && $this->_year == $evtYear)
$firstDay = intval($evtDay);
for($i=$firstDay; $i<=$lastDay; $i+=7)
$this->{$var}[$i][] = $obj;
}
/**
* Fortnight (14 nights), Bi-Weekly (Every other Week) Events
*/
elseif($row['recurring'] == 3)
{
$day = date('w', strtotime($row['event_date']));
$firstDay = getFirstDay($this->_month, $day, $this->_year);
if($this->_month == $evtMonth && $this->_year == $evtYear)
$firstDay = intval($evtDay);
for($i=$firstDay; $i<=$lastDay; $i+=14)
$this->{$var}[$i][] = $obj;
}
/**
* Monthly Events
*/
elseif($row['recurring'] == 2)
{
if($this->_month != $evtMonth || $this->_year != $evtYear)
{
$day = date('w', strtotime($row['event_date']));
$firstDay = getFirstDay($this->_month, $day, $this->_year);
if($evtDay <= 7)
$firstDay = $firstDay;
elseif($evtDay <= 14)
$firstDay += 7;
elseif($evtDay <= 21)
$firstDay += 14;
elseif($evtDay <= 28)
$firstDay += 21;
else
$firstDay = getLastDay($this->_month, $day, $this->_year);
}
else
$firstDay = intval($evtDay);
$this->{$var}[$firstDay][] = $obj;
}
/**
* Annual Events
*/
elseif($row['recurring'] == 1)
{
$this->{$var}[$evtDay][] = $obj;
}
else
$this->writeErrorLog($row);
}
}
return;
}
I use it in an object I create, but it does its job. And it's split 50/50 on the DB side and the PHP side. I only get those items I need, and I only reference the item object as many times as I need it in that month.