All dates that you have are indicated in the same year. You can convert each date to the number of days this year.
Then you will have an array of numbers. For this array, you can simply do the following:
Another way is to calculate the next date based on the previous one, and then compare it with the next date in the array. If both are equal, increase the current time interval; if not, create a new time interval. Then reduce the array to time intervals:
$consecutiveDates = function ($result, $date) { if ($count = count($result)) { $next = clone $result[$count - 1][1]; $next->add(new DateInterval('P1D')); } $date = new DateTime($date); if (!$count || $date != $next) { $result[$count++] = [$date]; } $result[$count - 1][1] = $date; return $result; }; $reduced = array_reduce($datearray, $consecutiveDates, []);
This gives the following result (for your array):
Array ( [0] => Array ( [0] => DateTime Object ( [date] => 2013-05-05 00:00:00 [timezone_type] => 3 [timezone] => Europe/London ) [1] => DateTime Object ( [date] => 2013-05-08 00:00:00 [timezone_type] => 3 [timezone] => Europe/London ) ) [1] => Array ( [0] => DateTime Object ( [date] => 2013-06-19 00:00:00 [timezone_type] => 3 [timezone] => Europe/London ) [1] => DateTime Object ( [date] => 2013-06-21 00:00:00 [timezone_type] => 3 [timezone] => Europe/London ) ) )
These two entries can now be easily displayed in your output style using the display function:
$consecutiveDatesString = function ($pair) { list($start, $end) = $pair; return $start == $end ? $start->format('j M') : $start->format($start->format('M') != $end->format('M') ? 'j M' : 'j') . $end->format(' - j M'); }; $consecutiveDatesStrings = array_map($consecutiveDatesString, $reduced);
This leads to a more compact result:
Array ( [0] => 5 - 8 May [1] => 19 - 21 Jun )
And finally, print separated by commas:
echo implode(', ', $consecutiveDatesStrings), "\n";
What gives, guess that:
5 - 8 May, 19 - 21 Jun