Skip to content

Instantly share code, notes, and snippets.

@alexbilbie
Last active September 28, 2015 22:38
Show Gist options
  • Save alexbilbie/1506589 to your computer and use it in GitHub Desktop.
Save alexbilbie/1506589 to your computer and use it in GitHub Desktop.
Recurring events with cron-like syntax
<?php
date_default_timezone_set('Europe/London');
function dd()
{
die(var_dump(func_get_args()));
}
function dp($i)
{
die(print_r($i));
}
function sort_multi_array($array, $key)
{
$keys = array();
for ($i=1; $i < func_num_args(); $i++)
{
$keys[$i-1] = func_get_arg($i);
}
$func = function($a, $b) use ($keys)
{
for ($i=0; $i < count($keys); $i++)
{
if ($a[$keys[$i]] !== $b[$keys[$i]])
{
return ($a[$keys[$i]] < $b[$keys[$i]]) ? -1 : 1;
}
}
return 0;
};
usort($array, $func);
return $array;
}
function matches($day_of_month = '*', $month = '*', $day_of_week = '*', $time)
{
if (($day_of_month !== '*') && ((int) date('d', $time) !== $day_of_month))
{
return false;
}
if (($month !== '*') && ((int) date('n', $time) !== $month))
{
return false;
}
if (($day_of_week !== '*') && ((int) date('w', $time) !== $day_of_week))
{
return false;
}
return true;
}
function mkevent($title, $repeat_from, $repeat_until, $duration, $minute, $hour, $day_of_month, $month, $day_of_week)
{
$e = new stdClass;
$e->title = $title;
$e->repeat_from = $repeat_from;
$e->repeat_until = $repeat_until;
$e->duration = $duration; // in minutes
$e->minute = $minute; // * = any minute, 1 through 59
$e->hour = $hour; // * = any hour, 1 through 59
$e->repeat_dayofmonth = $day_of_month; // * = any day, 1 through 31
$e->month = $month; // * = any month, 1 = Jan, 12 = Dec
$e->repeat_dayofweek = $day_of_week; // * = any day, 0 = sunday, 6 = saturday
return $e;
}
$events = array();
// Recurring events
$events[] = mkevent('Weekly Tuesday Meeting', '2011-12-01', '2011-12-31', 60, 30, 11, '*', '*', 2);
$events[] = mkevent('Weekly Friday Meeting', '2011-12-01', '2011-12-31', 30, '*', 16, '*', '*', 5);
$events[] = mkevent('Christmas', '2010-01-01', '2015-12-31', 1440, 0, 0, 25, 12, '*');
// Induvidual events
$events[] = mkevent('Lunch with John Doe', '2011-12-21', '2011-12-21', 30, '*', 12, '*', '*', '*');
$events[] = mkevent('Cinema', '2011-12-14', '2011-12-14', 180, '*', 19, '*', '*', '*');
$results = array();
foreach ($events as $k => $event)
{
$start = strtotime($event->repeat_from);
$end = strtotime($event->repeat_until);
for ($current = $start; $current <= $end; $current += 86400)
{
$event->hour = ($event->hour === '*') ? 0 : $event->hour;
$event->minute = ($event->minute === '*') ? 0 : $event->minute;
$newtime = mktime($event->hour, $event->minute, 0, date('m', $current), date('d', $current), date('Y', $current));
if ($i = matches($event->repeat_dayofmonth, $event->month, $event->repeat_dayofweek, $newtime))
{
$results[] = array(
'event_title' => $event->title,
'english_start' => date('l jS F Y H:i', $newtime),
'english_end' => date('l jS F Y H:i', ($newtime + ($event->duration * 60))),
'unix_start' => $newtime,
'unix_end' => $newtime + ($event->duration * 60)
);
}
}
}
print_r(sort_multi_array($results, 'unix_start'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment