php - 如何使用多维数组以及重叠检查从开始时间和结束时间获取总小时数?
问题描述
我有一个下面的场景,我只需要检查特定日期数组中的重叠并获得总参加时间。
array (
'2020-07-14' =>
array (
'total_attended_hours' => 0,
0 =>
array (
'start_time' => '09:00:00',
'end_time' => '13:00:00',
'hours' => '4 hours 0 mins',
),
1 =>
array (
'start_time' => '13:30:00',
'end_time' => '16:30:00',
'hours' => '3 hours 0 mins',
),
2 =>
array (
'start_time' => '09:00:00',
'end_time' => '14:00:00',
'hours' => '5 hours 0 mins',
),
),
'2020-07-15' =>
array (
'total_attended_hours' => 0,
0 =>
array (
'start_time' => '13:30:00',
'end_time' => '17:00:00',
'hours' => '3 hours 30 mins',
),
1 =>
array (
'start_time' => '09:00:00',
'end_time' => '14:00:00',
'hours' => '5 hours 0 mins',
),
),
)
在上面的例子中,2020-07-14
我们有start_time and
end_time total_attended_hours :-
7 should be equals to
hours 30 mins``
接下来2020-07-15
应该是total_attended_hours
=8 hours 0 mins
以下数组的新问题
$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',
],
],
];
结果 :-
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
)
[total_attended_hours] => 03:15:00
应该在哪里[total_attended_hours] => 03:30:00
解决方案
在这里你得到了算法:
- 对于每组时间预订,请执行以下操作
- 找到最小的
start_time
- 将
duration
介于start_time
和之间添加end_time
到sum
- 查找下一个最小的 Time-Booking 通过
start_time
- IF
current_end_time
<previous_end_time
跳转到 4 END IF - IF
start_time
<从END IFprevious_end_time
中减去差值sum
- 在和
duration
之间添加start_time
end_time
- 跳到 4 直到没有匹配的元素。
快乐编码:)
编辑 - 添加更干净的实现
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']);
if ($currentEnd < $previousEnd) continue; // this has been added
$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;
}
工作示例。
推荐阅读
- c++ - 静态 constexpr 成员函数在非模板类 C++ 中不可调用
- javascript - 在 mongodb 中按给定值递增所有嵌套值
- java - 无法让 Java 和 C# 通过套接字进行通信
- list - Kotlin - 集合 plus() × plusElement() 的区别
- swift - 执行异步云函数的问题
- reactjs - 用于构建的 React 应用的 App Engine app.yaml 处理程序
- android - 我们可以在底部 Appbar 中实现折叠工具栏的行为吗?
- regex - 如何使用正则表达式提取器从jmeter中的响应中提取值
- c++11 - 在 C++ 中进行方法链接时如何避免复制
- javascript - 找到SVG路径的方向