PHP получить самое близкое время к данному массиву раз - PullRequest
0 голосов
/ 13 ноября 2018

У меня есть массив с именем $timeslots с временными интервалами, такими как:

array:32 [▼
  0 => "2018-12-15T12:00:00.0000000"
  1 => "2018-12-15T12:15:00.0000000"
  2 => "2018-12-15T12:30:00.0000000"
  3 => "2018-12-15T12:45:00.0000000"
  4 => "2018-12-15T13:00:00.0000000"
  5 => "2018-12-15T13:15:00.0000000"
  6 => "2018-12-15T13:45:00.0000000"
  7 => "2018-12-15T14:15:00.0000000"
  8 => "2018-12-15T14:30:00.0000000"
  9 => "2018-12-15T14:45:00.0000000"
  10 => "2018-12-15T15:00:00.0000000"
  11 => "2018-12-15T15:15:00.0000000"
  12 => "2018-12-15T15:30:00.0000000"
  13 => "2018-12-15T15:45:00.0000000"
  14 => "2018-12-15T16:15:00.0000000"
  15 => "2018-12-15T16:45:00.0000000"
  16 => "2018-12-15T17:00:00.0000000"
  17 => "2018-12-15T17:30:00.0000000"
  18 => "2018-12-15T17:45:00.0000000"
  19 => "2018-12-15T18:30:00.0000000"
  20 => "2018-12-15T18:45:00.0000000"
  21 => "2018-12-15T19:15:00.0000000"
  22 => "2018-12-15T19:45:00.0000000"
  23 => "2018-12-15T20:15:00.0000000"
  24 => "2018-12-15T20:45:00.0000000"
  25 => "2018-12-15T21:00:00.0000000"
  26 => "2018-12-15T21:15:00.0000000"
  27 => "2018-12-15T21:30:00.0000000"
  28 => "2018-12-15T21:45:00.0000000"
  29 => "2018-12-15T22:00:00.0000000"
  30 => "2018-12-15T22:15:00.0000000"
  31 => "2018-12-15T22:30:00.0000000"
]

Кроме того, у меня есть переменная типа:

$expected_time = 2018-12-15T18:00:00.0000000; // this can be different value, so its not unique value

$ Ожидаемое время никогда не входит в массив $timeslotsно мне нужно найти ближайшее значение к $ Ожидаемое время ... Как я могу это сделать?

Как получить значение ближайшего временного интервала из массива $timeslots до $expected_time и рассчитать разницу в минутах?

Есть идеи?

Ответы [ 3 ]

0 голосов
/ 13 ноября 2018

Вот одно решение, соответствующее вашим требованиям:

function findClosestDate($expectedDate,$dates)
{

    $differenceInMinutes = null; 
    $expectedDate = new DateTime($expectedDate);
    $expectedDateEpoch = $expectedDate->getTimestamp();
    $returnIndex = -1;

    for($i = 0; $i<count($dates); $i++)
    {
        $dateObject = new DateTime($dates[$i]);
        $dateEpoch = $dateObject->getTimestamp();
        $difference = abs($expectedDateEpoch-$dateEpoch);
        $difference = $difference/60;
        if($differenceInMinutes === null || $difference < $differenceInMinutes)
        {
            $differenceInMinutes = $difference;
            $returnIndex = $i;
        }
    }

    return array(
        "closest" => $dates[$returnIndex],
        "difference" => $differenceInMinutes
    ) ;
}

Это использует класс DateTime для создания объекта DateTime и получения соответствующего timestamp.Затем минуты рассчитываются по абсолютной разнице между expectedDate и записью в массиве dates.После итерации по всему массиву самое близкое совпадение и разность возвращаются в одном массиве.

0 голосов
/ 13 ноября 2018

, поскольку ваш список уже отсортирован - вы можете поместить элемент в массив и снова использовать сортировку - и это будет намного быстрее, чем вычисление различий в каждой итерации.

<?php
$timeslots = [
    ...
];

$expected_time = "2018-12-15T18:00:00.0000000";
$counter = count($timeslots);
$timeslots = array_flip($timeslots);
$timeslots[$expected_time] = $counter;
ksort($timeslots);

while (key($timeslots) !== $expected_time) {
    $prev = key($timeslots);
    next($timeslots);
}

next($timeslots);
$next = key($timeslots);

$expected_time = new \DateTime($expected_time);
$closestDiff = min(($expected_time)->diff(new \DateTime($prev)), (new \DateTime($next))->diff($expected_time));
var_dump($closestDiff->i);
0 голосов
/ 13 ноября 2018

Как Нико упоминал в комментариях, это довольно просто. Просто зацикливание и вычисление разницы во времени.

$timeslots = [...];
$expected_time = "2018-12-15T18:00:00.0000000";
$timestamp = strtotime($expected_time);
$diff = null;
$index = null;

foreach ($timeslots as $key => $time) {
    $currDiff = abs($timestamp - strtotime($time));
    if (is_null($diff) || $currDiff < $diff) {
        $index = $key;
        $diff = $currDiff;
    }
}

echo $timeslots[$index];
...