首页 > 解决方案 > 如何使用多维数组以及重叠检查从开始时间和结束时间获取总小时数?

问题描述

我有一个下面的场景,我只需要检查特定日期数组中的重叠并获得总参加时间。

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 tohours 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

标签: phparraysdatetimetime

解决方案


在这里你得到了算法:

  1. 对于每组时间预订,请执行以下操作
  2. 找到最小的start_time
  3. duration介于start_time和之间添加end_timesum
  4. 查找下一个最小的 Time-Booking 通过start_time
  5. IF current_end_time<previous_end_time跳转到 4 END IF
  6. IF start_time<从END IFprevious_end_time中减去差值sum
  7. 在和duration之间添加start_timeend_time
  8. 跳到 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;
}

工作示例


推荐阅读