Skip to content

Instantly share code, notes, and snippets.

@reinink
Last active October 23, 2020 15:45
Show Gist options
  • Save reinink/597f259cf0e8fe82df17 to your computer and use it in GitHub Desktop.
Save reinink/597f259cf0e8fe82df17 to your computer and use it in GitHub Desktop.
Given multiple periods of time in a day, that may overlap, calculate the sum of all the periods, in hours.
<?php
$periods = [
[new DateTime('8AM'), new DateTime('5PM')], // 9 hours
[new DateTime('8AM'), new DateTime('5PM')], // 9 hours
[new DateTime('10AM'), new DateTime('12PM')], // 2 hours
[new DateTime('12PM'), new DateTime('5PM')], // 5 hours
[new DateTime('7PM'), new DateTime('8PM')], // 1 hour
[new DateTime('9AM'), new DateTime('4PM')], // 7 hours
];
// Result: 10
echo total_hours_per_day($periods);
<?php
/**
* Calculates the total hours per day, considering period overlaps.
* @param array $periods
* @return integer
*/
function total_hours_per_day($periods)
{
ksort($periods);
do {
$count = count($periods);
foreach ($periods as $key1 => $period1) {
foreach ($periods as $key2 => $period2) {
if ($key2 > $key1 and $period1[0] <= $period2[1] and $period1[1] >= $period2[0]) {
$periods[] = [min($period1[0], $period2[0]), max($period2[1], $period1[1])];
unset($periods[$key1], $periods[$key2]);
}
}
}
} while ($count > count($periods));
return array_reduce($periods, function ($total, $period) {
return $total + $period[0]->diff($period[1])->h;
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment