Recurring Events

Hi guys, I’m in search of a function that can calculate from a given date when an event would recur and then possibly return everything in an array. I’ve been trying to do this all day with no luck. Below is what I kind of already have.

	
function get_events($origDate, $startDate, $endDate, $recurIntval)
{
	$events = array();
	
	$dateDiff = $origDate - $startDate;
	
	// Needs to be more calculations here
	
	while ($recurDate >= $startDate && $recurDate <= $endDate)
	{
		$events[] = array('date' => $recurDate);
	
		$recurDate += $recurIntval;
	}
	
	return $events;
}

Assuming that all the parameters are in seconds. If anyone could help me out, I’ll greatly appreciate it.

Can you give an example?

Well let’s say for example, 25th of December is Christmas (which is 1293235200 seconds for this year), we know that that comes every year same date so if I add on 31536000 seconds (1 year) to that, I’ll get 2011’s Christmas. But I also want to constrain the events returned based on startDate and endDate (because it’s for a calendar).

<?php
	$origDate = 1293235200; // 25th of December;
	$recurIntval = 31536000; // 1 year
	$startDate = 1291161600; // 1st of December
	$endDate = 1293753600; // 31st of December
?>

Sorry, not sure what you actually want to achieve, but adding 31536000 won’t work due to leap years, try strtotime(‘+1 year’, $time)

Hmm, that’s what I was originally doing but I thought I might be able to save time by just doing calculation when it’s added the database. Good to know, thanks.

You’ll have trouble on a leap year.

How about using strtotime ?


$year = 2011;
$origDate = strottime('25 december ' . $year);
$reoccur = '+1 year';
$nextYear = strtotime($reoccur, $origDate);

I finally got the sucker to work! Thanks for the info about strtotime, that’s what I really needed all along.

For anyone interested,

<?php
$type = array('day', 'week', 'month', 'year');
		
$date = strtotime($event['date']);
$interval = $type[$event['interval']];
$frequency = $event['frequency'];
$diff = $start - $date;

if ($diff > 0)
{	
	$days = floor($diff/86400);
	$startDate = strtotime("+$days day", $date);
}
else
{
	$start = $date;
}
			
for ($repeat = $start; $repeat <= $end; $repeat = strtotime("+$frequency $interval", $repeat))
{
	$events[] = array(
		'date' => $repeat,
	);
}
?>

$event is array from the database. $start and $end are in seconds, and is the range.

EDIT: Spoke too soon, the range isn’t working.
EDIT2: Okay now it’s working, converting seconds to days and then rounding that value seems to have fixed it.

If you have PHP 5.3 available, this is as simple as:


$date = new DateTime($event);
$recurrance = $date->modify($interval);

Don’t know if that’s an option, but it’s a heck of a lot simpler than the awful strtotime functions.

Check out http://us2.php.net/manual/en/class.datetime.php for details.

You can actually use DateTime + DateInterval + DatePeriod.

Something I just noticed, is the DateTime constructor can’t take a unix timestamp, and they don’t provide a factory for it either. That’s pretty lame…all you get is $dt->setTimestamp()

I ran into the same thing earlier this week. The DT class actually provides a couple of different methods for time comparison (add, modify and sub) and is nice because you can do simple comparisons between different objects natively ($datetime1 >= $datetime2, etc). It’s a solid class, but the fact that there’s only a String constructor bugs me.

I guess that they’re making plans to do away with the 32-bit timestamp, in prepreation for dealing with the 2038 date problem.