Web design, programming, graphics, and pretty much anything else I care about.

Creating date repeat rules

Because Date doesn't play well with drupal_execute(), you have to use node_save() to insert/update nodes. If those nodes have a date field that uses repeats, you have to manually create the date array and repeat rule. ugh!

This website has some helpful information on the format of the RRULE standard. http://www.kanzaki.com/docs/ical/rrule.html

// Create the RRULE.
// For this example, we will assume the interval is daily.
// You will need code to figure out what the interval is for your the specific date.
// $repeat_end is the date that would be chosen in the node add/edit form. Ymd\THis format.
$frequency = 'DAILY';
$interval = '1';
$rrule = "RRULE:FREQ=$frequency;INTERVAL=$interval;UNTIL=$repeat_end;WKST=SU";

// Get the exceptions, which are skipped dates.
// The code to figure out the exceptions is particular to your project.
$exceptions = array();
while (...) {
$exceptions[] = date('Y-m-d', $exception_date);
// The new line is annoyingly important for the EXDATE.
if (!empty($exceptions)) $rrule .= PHP_EOL . 'EXDATE:' . implode('Z,', $exceptions);

// This will return an array of dates.
// $start_date and $end_date are in Unix timestamp format.
$repeats = date_repeat_calc($rrule, date('Y-m-d H:i:s', $start_date), $end_date, $exceptions, 'America/New_York');

// Added repeat dates.
// Every repeat date gets stored with a start, end, and rrule.
$my_array->dates = array();
$repeats as $key => $date) {
// Calculate end date. Repeat's timestamp + diff between the original start and end.
$end_timestamp = strtotime($date) + (date('U', $end_date) - date('U', $start_date));
$end_datetime = date('Y-m-d H:i:s', $end_timestamp);
$date_values = array(
'value' => gmdate('Y-m-d H:i:s', strtotime($date)),
'value2' => gmdate('Y-m-d H:i:s', strtotime($end_datetime)),
'rrule' => $rrule,

// To add to your node before doing node_save();
$node->field_my_date = $date_values;