PHP 获得最接近给定时间数组的时间
PHP get closest time to given array of times
我有一个名为 $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
$expected_time 永远不会进入数组 $timeslots
但我需要找到最接近 $expected_time 的值...我该怎么做?
如何从数组 $timeslots
到 $expected_time
中获取最接近的时隙值并计算以分钟为单位的差异?
有什么想法吗?
正如 Nico 在评论中提到的,它非常简单。只是循环计算时间差。
$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
class 创建一个 DateTime
对象并获得相应的 timestamp
。然后根据 expectedDate
和 dates
数组中的条目之间的绝对差值计算分钟数。遍历整个数组后,最接近的匹配和差异在一个数组中返回。
因为您的列表已经排序 - 您可以将元素放入数组并再次使用排序 - 这样会比在每次迭代中计算差异快得多。
<?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);
我有一个名为 $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
$expected_time 永远不会进入数组 $timeslots
但我需要找到最接近 $expected_time 的值...我该怎么做?
如何从数组 $timeslots
到 $expected_time
中获取最接近的时隙值并计算以分钟为单位的差异?
有什么想法吗?
正如 Nico 在评论中提到的,它非常简单。只是循环计算时间差。
$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
class 创建一个 DateTime
对象并获得相应的 timestamp
。然后根据 expectedDate
和 dates
数组中的条目之间的绝对差值计算分钟数。遍历整个数组后,最接近的匹配和差异在一个数组中返回。
因为您的列表已经排序 - 您可以将元素放入数组并再次使用排序 - 这样会比在每次迭代中计算差异快得多。
<?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);