Получить доступное время из массива занятых часов PHP - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть массив php забронированного времени как:

print_r($data)

Illuminate\Support\Collection Object
(
    [items:protected] => Array
        (
            [0] => stdClass Object
                (
                    [id] => 1
                    [start_date] => 2019-09-26
                    [start_time] => 07:00:00
                    [end_date] => 2019-09-26
                    [end_time] => 09:00:00
                )

            [1] => stdClass Object
                (
                    [id] => 4
                    [start_date] => 2019-09-26
                    [start_time] => 12:00:00
                    [end_date] => 2019-09-26
                    [end_time] => 14:00:00
                )

            [2] => stdClass Object
                (
                    [id] => 9
                    [start_date] => 2019-09-26
                    [start_time] => 16:00:00
                    [end_date] => 2019-09-26
                    [end_time] => 17:00:00
                )

            [3] => stdClass Object
                (
                    [id] => 13
                    [start_date] => 2019-09-26
                    [start_time] => 19:00:00
                    [end_date] => 2019-09-26
                    [end_time] => 20:00:00
                )

            [4] => stdClass Object
                (
                    [id] => 2
                    [start_date] => 2019-09-27
                    [start_time] => 07:00:00
                    [end_date] => 2019-09-27
                    [end_time] => 08:00:00
                )

            [5] => stdClass Object
                (
                    [id] => 5
                    [start_date] => 2019-09-27
                    [start_time] => 12:00:00
                    [end_date] => 2019-09-27
                    [end_time] => 14:00:00
                )

            [6] => stdClass Object
                (
                    [id] => 10
                    [start_date] => 2019-09-27
                    [start_time] => 16:00:00
                    [end_date] => 2019-09-27
                    [end_time] => 18:00:00
                )

            [7] => stdClass Object
                (
                    [id] => 14
                    [start_date] => 2019-09-27
                    [start_time] => 19:00:00
                    [end_date] => 2019-09-27
                    [end_time] => 20:00:00
                )

            [8] => stdClass Object
                (
                    [id] => 3
                    [start_date] => 2019-09-28
                    [start_time] => 07:00:00
                    [end_date] => 2019-09-28
                    [end_time] => 10:00:00
                )

            [9] => stdClass Object
                (
                    [id] => 6
                    [start_date] => 2019-09-28
                    [start_time] => 12:00:00
                    [end_date] => 2019-09-28
                    [end_time] => 13:00:00
                )

            [10] => stdClass Object
                (
                    [id] => 11
                    [start_date] => 2019-09-28
                    [start_time] => 16:00:00
                    [end_date] => 2019-09-28
                    [end_time] => 17:00:00
                )

            [11] => stdClass Object
                (
                    [id] => 15
                    [start_date] => 2019-09-28
                    [start_time] => 19:00:00
                    [end_date] => 2019-09-28
                    [end_time] => 20:00:00
                )

        )

)

Теперь я хочу найти подробную информацию о доступных часах для каждого дня.Чтобы проверить это, давайте рассмотрим рабочие часы от 07:00:00 до 20:00:00

Теперь я хочу найти доступное время между этими часами, т.е. 07:00:00 до 20:00:00, отфильтровав все вышеуказанное забронированное время.

$available_hour =  => Array(
            [2019-09-26] => Array(
                        [0] => Array(
                            ['start'] => 09:00:00
                            ['end'] => 12:00:00
                        )
                        [1] => Array(
                            ['start'] => 14:00:00
                            ['end'] => 16:00:00
                        )
                        [2] => Array(
                            ['start'] => 17:00:00
                            ['end'] => 19:00:00
                        )
            )
            [2019-09-27] => Array(
                        [0] => Array(
                            ['start'] => 08:00:00
                            ['end'] => 12:00:00
                        )
                        [1] => Array(
                            ['start'] => 14:00:00
                            ['end'] => 16:00:00
                        )
                        [2] => Array(
                            ['start'] => 18:00:00
                            ['end'] => 19:00:00
                        )
            )
            [2019-09-28] => Array(
                        [0] => Array(
                            ['start'] => 10:00:00
                            ['end'] => 12:00:00
                        )
                        [1] => Array(
                            ['start'] => 13:00:00
                            ['end'] => 16:00:00
                        )
                        [2] => Array(
                            ['start'] => 17:00:00
                            ['end'] => 19:00:00
                        )
            )
)

Это основная идея, я видел подобную проблему при переполнении стека, Получение доступных временных диапазонов из массива занятых временных диапазонов , однако я хочу разобратьсяэто в php вместо js.

Я старался изо всех сил представлять образец массива данных (хотя это полный массив вместо объекта), с ним можно работать.Вот ссылка sandbox .

Ответы [ 3 ]

0 голосов
/ 24 сентября 2019

Попробуйте этот код ..

$res = [];
foreach($x as $value)
{
    if(array_key_exists($value['start_date'],$res))
    {
        end($res[$value['start_date']]);         // move the internal pointer to the end of the array
        $key = key($res[$value['start_date']]);
            if(empty($res[$value['start_date']][$key]['end']))
            {
                if($value['start_time'] >= '07:00:00' && $value['start_time'] <= '20:00:00')
                {
                    $res[$value['start_date']][$key]['end'] = $value['start_time']; 
                }
            }
            else
            {
                if($value['end_time'] >= '07:00:00' && $value['end_time'] <= '20:00:00')
                {
                    $res[$value['start_date']][] = ['start' => $value['end_time']];
                }
            }
            if(!empty($res[$value['start_date']][$key]['start']))
            {
                if($value['end_time'] >= '07:00:00' && $value['end_time'] <= '20:00:00')
                {
                    $res[$value['start_date']][] = ['start' => $value['end_time']]; 
                }
            }
    }

    else
    {
        if($value['start_date'] >= '07:00:00' && $value['start_date'] <= '20:00:00')
        {
             $res[$value['start_date']][] = ['start' => "07:00:00",'end' => $value['start_time']];
             end($res[$value['start_date']]);         
             $key = key($res[$value['start_date']]);
             $res[$value['start_date']][++$key] = ['start' =>  $value['end_time']];

        }
    }
}
foreach($res as $key => $result)
{
foreach($result as $k => $v)
{
    if(!array_key_exists('end',$v))
    {
        unset($result[$k]);
    }
}
$new[$key] = $result;
}

Окончательный результат будет в переменной $new.

0 голосов
/ 24 сентября 2019

Вот небольшой трюк, предполагая, что структура массива / объекта содержит «элементы».

Рабочий пример: https://3v4l.org/Wat8i работает с PHP 5.4 +.

<?php

$datetimes = [
    "items" => [
        [
            "id" => 1,
            "start_date" => "2019-09-26",
            "start_time" => "07:00:00",
            "end_date" => "2019-09-26",
            "end_time" => "09:00:00"
        ],
        [
            "id" => 4,
            "start_date" => "2019-09-26",
            "start_time" => "12:00:00",
            "end_date" => "2019-09-26",
            "end_time" => "14:00:00"
        ],
        [
            "id" => 9,
            "start_date" => "2019-09-26",
            "start_time" => "16:00:00",
            "end_date" => "2019-09-26",
            "end_time" => "17:00:00"
        ],
        [
            "id" => 13,
            "start_date" => "2019-09-26",
            "start_time" => "19:00:00",
            "end_date" => "2019-09-26",
            "end_time" => "20:00:00"
        ],
        [
            "id" => 2,
            "start_date" => "2019-09-27",
            "start_time" => "07:00:00",
            "end_date" => "2019-09-27",
            "end_time" => "08:00:00"
        ],
        [
            "id" => 5,
            "start_date" => "2019-09-27",
            "start_time" => "12:00:00",
            "end_date" => "2019-09-27",
            "end_time" => "14:00:00"
        ],
        [
            "id" => 10,
            "start_date" => "2019-09-27",
            "start_time" => "16:00:00",
            "end_date" => "2019-09-27",
            "end_time" => "18:00:00"
        ],
        [
            "id" => 14,
            "start_date" => "2019-09-27",
            "start_time" => "19:00:00",
            "end_date" => "2019-09-27",
            "end_time" => "20:00:00"
        ],
        [
            "id" => 3,
            "start_date" => "2019-09-28",
            "start_time" => "07:00:00",
            "end_date" => "2019-09-28",
            "end_time" => "10:00:00"
        ],
        [
            "id" => 6,
            "start_date" => "2019-09-28",
            "start_time" => "12:00:00",
            "end_date" => "2019-09-28",
            "end_time" => "13:00:00"
        ],
        [
            "id" => 11,
            "start_date" => "2019-09-28",
            "start_time" => "16:00:00",
            "end_date" => "2019-09-28",
            "end_time" => "17:00:00"
        ],
        [
            "id" => 15,
            "start_date" => "2019-09-28",
            "start_time" => "19:00:00",
            "end_date" => "2019-09-28",
            "end_time" => "20:00:00"
        ]
    ]
];

$openinghours = [];

function openinghours($times) {

    global $openinghours;

    $openinghours[$times["start_date"]][] = [
        "start" => $times["start_time"],
        "end" => $times["end_time"]
    ];

}

array_map("openinghours", $datetimes["items"]);

var_dump($openinghours);

Он в основном создает новый массив без изменения старого и без необходимости в операторах.

[EDIT1]

И быстрая дополнительная функция foreach() для отображениядаты и время: https://3v4l.org/uhUeS

foreach($openinghours as $date => $times) {
    echo "{$date} : {$times[0]["start"]} - " . end($times)["end"] . "\n";
}

[EDIT2]

Если вы ожидаете, что люди или вы сами измените часы работы так, чтобы id 1может иметь от 07:00:00 до 20:00:00, я предлагаю вам изменить структуру вывода, чтобы игнорировать start и end и просто выбрать первую и последнюю из дат: https://3v4l.org/jMvCP

function openinghours($times) {

    global $openinghours;

    $openinghours[$times["start_date"]][] = $times["start_time"];
    $openinghours[$times["start_date"]][] = $times["end_time"];

    sort($openinghours[$times["start_date"]]);

}

array_map("openinghours", $datetimes["items"]);

var_dump($openinghours);

foreach($openinghours as $date => $times) {
    echo "{$date} : {$times[0]} - " . end($times) . "\n";
}
0 голосов
/ 24 сентября 2019
$start = "";
$starting_hour = "07:00:00";
$ending_hour = "20:00:00";
foreach ($data as $key => $item) {
    if(isset($new_arr[$item['start_date']])) {
     $end = $item['start_time'];
     $new_arr[$item['start_date']][] = ['start'=> $start, 'end'=> $end];
     $start = $item['end_time'];
    } else {
     $new_arr[$item['start_date']] = [];
     if( $item['start_time'] > $starting_hour)
        $new_arr[$item['start_date']][] = ['start'=> $starting_hour, 'end'=> 
        $item['start_time']];
     $start = $item['end_time'];
     continue;
    }

    if ( $start < $ending_hour ) {
       if ( !isset($data[$key+1]) ) {
         $new_arr[$item['start_date']][] = ['start'=> $start, 'end'=> 
         $ending_hour];
       } else {
         if( $item['start_date'] != $data[$key+1]['start_date']) {
            $new_arr[$item['start_date']][] = ['start'=> $start, 'end'=> 
            $ending_hour];
         }
      }
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...