亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 PHP 從帶有 start_time 和 end_time 的多維數組中查找總小時數?

使用 PHP 從帶有 start_time 和 end_time 的多維數組中查找總小時數?

PHP
一只萌萌小番薯 2023-08-19 17:37:34
我正在嘗試使用start_time和計算正確的總小時數end_time這里我使用的算法是由@Pilan 提供的:對于每組時間預訂,執行以下操作找到最小的start_time將和duration之間添加到start_timeend_timesum查找下一個最小的時間預訂start_timeIF start_time<previous_end_time減去sumEND IF的差值在和duration之間添加start_timeend_time跳到4,直到沒有匹配的元素為止。使用上面的內容我成功創建了以下代碼:<?phpclass Helper {         public static function minToHour($minutes)    {        if (empty($minutes)) {            return 0;        }        $hours = floor($minutes / 60);        $min = $minutes - ($hours * 60);        return $hours . ":" . $min;    }public static function getMinsBetweenTwoTimes($start, $end)    {        $datetime1 = strtotime($start);        $datetime2 = strtotime($end);        $interval = abs($datetime2 - $datetime1);        $minutes = round($interval / 60);        return $minutes;    }   }$array =array (  '2020-07-14' =>   array (      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 (    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',    ),  ),);
查看完整描述

2 回答

?
慕虎7371278

TA貢獻1802條經驗 獲得超4個贊

這是我對你的問題的解決方案。


我不知道我是否理解正確,但基本上這是算法:


1-將所有時間字符串轉換為整數并對參加時間段的每個日期列表進行排序。


2- 合并每個日期的重疊時段,例如,如果一個時段從 9 點到 12 點,另一個時段從 11 點到 13 點,則將其合并為從 9 點到 13 點的單個時段。


3- 將每個日期的所有參加時間相加。


<?php


$array = [

? ? '2020-07-14' =>[

? ? ? ? [

? ? ? ? ? ? 'start_time' => '09:00:00',

? ? ? ? ? ? 'end_time' => '13:00:00',

? ? ? ? ? ? 'hours' => '4 hours 0 mins',

? ? ? ? ],

? ? ? ? [

? ? ? ? ? ? 'start_time' => '13:30:00',

? ? ? ? ? ? 'end_time' => '16:30:00',

? ? ? ? ? ? 'hours' => '3 hours 0 mins',

? ? ? ? ],


? ? ? ? [

? ? ? ? ? ? 'start_time' => '09:00:00',

? ? ? ? ? ? 'end_time' => '14:00:00',

? ? ? ? ? ? 'hours' => '5 hours 0 mins',

? ? ? ? ],

? ? ? ? [

? ? ? ? ? ? 'start_time' => '17:00:00',

? ? ? ? ? ? 'end_time' => '18:00:00',

? ? ? ? ? ? 'hours' => '1 hours 0 mins',

? ? ? ? ]

? ? ],

? ? '2020-07-15' => [

? ? ? ? [

? ? ? ? ? ? 'start_time' => '09:00:00',

? ? ? ? ? ? 'end_time' => '14:00:00',

? ? ? ? ? ? 'hours' => '5 hours 0 mins',

? ? ? ? ],

? ? ? ? [

? ? ? ? ? ? 'start_time' => '13:30:00',

? ? ? ? ? ? 'end_time' => '17:00:00',

? ? ? ? ? ? 'hours' => '4 hours 30 mins',

? ? ? ? ]

? ? ],

];


// Convert all times strings into integers and sort each day list

// by the start time

$r = parseTimesAndSort($array);


// Combine overlaping periods in a single period

$r = flatternOverlaps($r);


// Sum all the periods in each date

$r = sumPeriods($r);


// Applly the result to the original array

foreach($r as $date => $item){

? ? $array[$date]['total_attended_hours'] = $item;

}


print_r($array);



/**

?* Given a time string returns the number of seconds from 00:00:00 as integer.

?* example: 09:30:10 => 34210 (9*3600 + 30*60 + 10)

?* @param $time

?* @return int

?*/

function timeToSeconds($time){

? ? $list = explode(":", $time);

? ? return $list[0] * 3600 + $list[1] * 60 + $list[2];

}



/**

?* Given an integer as seconds returns the time string in 00:00:00 format.

?* example: 34210 => 09:30:10

?* @param $value

?* @return string

?*/

function secondsToTime($value){

? ? $hours = floor($value/3600);

? ? $min = floor(($value%3600) / 60);

? ? $secods = floor($value % 60);


? ? return str_pad($hours, 2, "0", STR_PAD_LEFT)

? ? ? ? .":".str_pad($min, 2, "0", STR_PAD_LEFT)

? ? ? ? .":".str_pad($secods, 2, "0", STR_PAD_LEFT);

}


/**

?* Function to compare two periods

?* @param $a

?* @param $b

?* @return int

?*/

function sortByStartTime($a, $b){

? ? if ($a['start_time'] == $b['start_time']){

? ? ? ? return 0;

? ? }

? ? return $a['start_time'] < $b['start_time'] ? -1 : 1;

}


/**

?* Parses the periods string times to integers and sorts them

?* @param $array

?* @return array

?*/

function parseTimesAndSort($array){

? ? $r = [];

? ? foreach($array as $date => $list){

? ? ? ? $current = [];

? ? ? ? foreach($list as $item){

? ? ? ? ? ? $current[] = [

? ? ? ? ? ? ? ? 'start_time' => timeToSeconds($item['start_time']),

? ? ? ? ? ? ? ? 'end_time' => timeToSeconds($item['end_time']),

? ? ? ? ? ? ];

? ? ? ? }

? ? ? ? usort($current, 'sortByStartTime');

? ? ? ? $r[$date] = $current;

? ? }

? ? return $r;

}


/**

?* Finds overlapping periods and combines them

?* @param $array

?* @return array

?*/

function flatternOverlaps($array){

? ? $r = [];

? ? foreach($array as $date => $list){

? ? ? ? $currentList = [];

? ? ? ? $prev = null;

? ? ? ? foreach($list as $item){

? ? ? ? ? ? if ($prev && $item['start_time'] < $prev['end_time']){

? ? ? ? ? ? ? ? if ($item['end_time'] > $prev['end_time']) {

? ? ? ? ? ? ? ? ? ? $prev['end_time'] = $item['end_time'];

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? else{

? ? ? ? ? ? ? ? $currentList[] = $item;

? ? ? ? ? ? }


? ? ? ? ? ? // Point prev to the last item in the current list

? ? ? ? ? ? $prev = &$currentList[count($currentList)-1];

? ? ? ? }

? ? ? ? unset($prev);

? ? ? ? $r[$date] = $currentList;

? ? }


? ? return $r;

}


/**

?* Sums the periods of each date

?* @param $array

?* @return array

?*/

function sumPeriods($array){

? ? $r = [];

? ? foreach($array as $date => $list){

? ? ? ? $seconds = array_reduce($list, function($carry, $item){ return $carry + $item['end_time'] - $item['start_time']; }, 0);

? ? ? ? $r[$date] = secondsToTime($seconds);

? ? }

? ? return $r;

}

查看完整回答
反對 回復 2023-08-19
?
神不在的星期二

TA貢獻1963條經驗 獲得超6個贊

我更改了 2 行,81 和 82(如下所示)。您不需要 strtotime($previous_end_time) 來比較它,因為時間是 24 小時制,而且當您減去時,您想要減去 $previous_end_time 而不是 $item['end_time']。

if (($item['start_time']) < $previous_end_time) {
  $sum -= Helper::getMinsBetweenTwoTimes($item['start_time'], $previous_end_time);
}


查看完整回答
反對 回復 2023-08-19
  • 2 回答
  • 0 關注
  • 150 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號