У меня есть массив под названием $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
а посчитать разницу в минутах?
Любая идея?
Как Нико упоминал в комментариях, это довольно просто. Просто цикл и расчет разницы во времени.
$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];
Вот одно решение, соответствующее вашим требованиям:
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
массив. После итерации по всему массиву самое близкое совпадение и разность возвращаются в одном массиве.
так как ваш список уже отсортирован — вы можете поместить элемент в массив и снова использовать sort — и это будет намного быстрее, чем вычисление diff в каждой итерации.
<?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);