Reputation: 729
I have a list of hours which I need to group into simplified contiguous chunks.
$array = [
[
"08:30",
"09:00",
"09:30",
"10:00",
"14:30",
"15:00",
"15:30",
"16:00",
"16:30"
],
[
"13:30",
"14:00",
"14:30",
"18:00",
"18:30",
"19:00"
]
];
and I'm trying to transform them to this format:
[
[
['08:30', '10:00'],
['14:30', '16:30']
],
[
['13:30', '14:30'],
['18:00', '19:00']
]
]
I need this for a jQuery plugin is using (Day Schedule Selector).
If the time difference is :30 minutes or less, then compact the times into a group.
Here is what I've tried:
$prepared = '';
foreach ($serialized as $day => $hours) {
$prepared_hours = array();
foreach ($hours as $hour) {
$prepared_hours[] = "['" . $hour . "']";
}
$prepared .= "'{$day}' : [". implode(',', $prepared_hours) . "],\n";
}
But the result was:
'0' : [['08:30'],['09:00'],['09:30'],['10:00'],['14:30'],['15:00'],['15:30'],['16:00'],['16:30']],
'1' : [['13:30'],['14:00'],['14:30'],['18:00'],['18:30'],['19:00']
Upvotes: 0
Views: 134
Reputation: 47894
While looping, keep track of the previously iterated time and compare that against the currently iterated time.
When starting a new group, destroy the previously created reference (if there is one yet), then declare a new reference and push it into the result array.
While working with contiguous times, push the current time into the second element of the reference variable specifically.
Code: (Demo)
function compactTimes(
array $times,
string $format = 'H:i',
string $separation = "30 minutes"
): array {
$result = [];
$prev = null;
foreach ($times as $time) {
if (!$prev || $time !== date("H:i", strtotime("+$separation $prev"))) {
unset($ref);
$ref = [$time, $time];
$result[] =& $ref;
} else {
$ref[1] = $time;
}
$prev = $time;
}
return $result;
}
var_export(
array_map('compactTimes', $array)
);
Upvotes: 2
Reputation: 149
Maybe this gets you started:
$start = new \DateTime('9:00');
$end = new \DateTime('14:00');
$period = new \DatePeriod($start,new \DateInterval('PT30M'),$end);
foreach ($period as $date) {
print $date->format('H:i') . '<br>';
}
Upvotes: -1