I am using below code to find out correct total hours but it is giving wrong results:- Using getSortedDays to sort my array Using addTotalAttendedHours to add total and add it into total attended hours,I have tried all possible methods of time and none of them are working. Even I tried removing abs and round but nothing is helping
<?php
declare(strict_types=1);
$data = [
'2020-07-14' =>
[
[
'start_time' => '14:15:00',
'end_time' => '17:45:00',
],[
'start_time' => '14:30:00',
'end_time' => '17:30:00',
],[
'start_time' => '14:30:00',
'end_time' => '17:30:00',
],
],
'2020-07-15' => [
[
'start_time' => '13:30:00',
'end_time' => '17:00:00',
],[
'start_time' => '09:00:00',
'end_time' => '14:00:00',
],
],
];
function getSortedDays(array $days): array {
return array_map(function (array $day) {
array_multisort(array_column($day, 'start_time'), SORT_ASC, $day);
return $day;
}, $days);
}
function addTotalAttendedHours(array $days): array {
$sortedDays = getSortedDays($days);
$days = array_map(function (array $day) {
$sum = (new DateTime())->setTimestamp(0);
$previousEnd = null;
foreach ($day as $time) {
$currentStart = new DateTimeImmutable($time['start_time']);
$currentEnd = new DateTimeImmutable($time['end_time']);
$sum->add($currentStart->diff($currentEnd));
if ($previousEnd !== null && $currentStart < $previousEnd) {
$sum->sub($currentStart->diff($previousEnd));
}
$previousEnd = $currentEnd;
}
$attendedSeconds = $sum->getTimestamp();
$day['total_attended_hours'] = sprintf(
'%02u:%02u:%02u',
$attendedSeconds / 60 / 60,
($attendedSeconds / 60) % 60,
$attendedSeconds % 60
);
return $day;
}, $sortedDays);
return $days;
}
echo "<pre>";
print_r(addTotalAttendedHours($data));
?>
Result
Array
(
[2020-07-14] => Array
(
[0] => Array
(
[start_time] => 14:15:00
[end_time] => 17:45:00
)
[1] => Array
(
[start_time] => 14:30:00
[end_time] => 17:30:00
)
[2] => Array
(
[start_time] => 14:30:00
[end_time] => 17:30:00
)
[total_attended_hours] => 03:15:00 //It should be 03:30:00
)
[2020-07-15] => Array
(
[0] => Array
(
[start_time] => 09:00:00
[end_time] => 14:00:00
)
[1] => Array
(
[start_time] => 13:30:00
[end_time] => 17:00:00
)
[total_attended_hours] => 08:00:00
)
)
Using above code I am getting wrong total_attended_hours
where for date 2020-07-14
the result should be 03:30:00
but it is giving 03:15:00
For the first day you have these time ranges:
14:15 – 17:45
14:30 – 17:30
14:30 – 17:30
And you are doing this:
You could change the subtracting line to:
$sum->sub($currentStart->diff(min($currentEnd, $previousEnd)));
This way you wouldn't subtract too much anymore, because you would subtract only the diff of the overlapping part until the minimum of current and previous end.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.