I currently allow for daily or weekly repeating events on my calendar app (using fullCalendar).
My view has a checkbox that activates two dropdowns: one for the repeat interval (daily, weekly) and one for the frequency (once, twice, etc).
$evt_interval_options = array( //this will be $row->interval in the model
'86400' => 'Daily',
'604800' => 'Weekly';
$evt_frequency_options = array( //this will be //$i in the model
'1' => '2',
'2' => '3',
<?php echo form_checkbox('evt_repeat', 'FALSE', FALSE, 'class="repeat_checkbox"');
echo form_dropdown('evt_interval', $evt_interval_options');
echo form_dropdown('evt_frequency', $evt_frequency_options'); ?>
This eventually reaches my model, which runs a loop checking if the event should repeat -- if so, it will factor in the interval ($row->interval
) and the frequency ($i
).
$cal_data[] = array(
'start' => strtotime($row->date_1 . ' ' . $row->time_1) + ($i ? ($row->interval * $i) : 0),
);
This works nicely to show multiple daily or weekly events based on a single record entry in the database.
The problem is with monthly and yearly. Since these will have variable number of seconds because
03/01/2011 00:00:00 --> 04/01/2011 00:00:00 ===> 2674800 seconds
04/01/2011 00:00:00 --> 05/01/2011 00:00:00 ===> 2592000 seconds
and so on for monthly and yearly differences
So how do I resolve this issue? Is there any function or strtotime
command that can help indicate precisely that a monthly should repeat on the e.g. 4th
or an yearly should repeat on July 4th
?
I am using PHP 5.2.14.
Thanks to all that answered - I solved the issue with this function by @akniep from the PHP.net manual on strtotime().
function get_x_months_to_the_future( $base_time = null, $months = 1 )
{
if (is_null($base_time))
$base_time = time();
$x_months_to_the_future = strtotime( "+" . $months . " months", $base_time );
$month_before = (int) date( "m", $base_time ) + 12 * (int) date( "Y", $base_time );
$month_after = (int) date( "m", $x_months_to_the_future ) + 12 * (int) date( "Y", $x_months_to_the_future );
if ($month_after > $months + $month_before)
$x_months_to_the_future = strtotime( date("Ym01His", $x_months_to_the_future) . " -1 day" );
return $x_months_to_the_future;
}
What this does is solve the issue of recurring monthly events on days 29, 30, 31
as well as Feb 28
.
I like this function because it solves my problem from a calendar app POV.
If the user requests a monthly recurring event beginning on Jan 31
normal strtotime
will behave erratically during February and any other month that does not have 31 days.
As I pointed out in a comment above, Google Calendar resolves this issue somewhat oddly by skipping months in which there's no such date.
I guess it's a matter of preference, but to me it makes better sense to offer placing the recurring event on the last day of the month - so in the Jan 31
example, recurring events will happen on Feb 28
Mar 31
Apr 30
and so on.
I placed this function in a loop that iterates as many recurrences the user requests and it works perfectly. It also works nicely in yearly events, for that I just pass 12
as the number of months.