This post几乎已经为我回答了这个问题,但我有一个特定的需求,并没有找到我在那里寻找的东西。这不在我的经验之外;无法完全绕过它,所以我真正需要的只是朝着正确的方向前进。
让我们说我有一个数组如下:
array(5) {
[0]=> "2013-02-18 05:14:54"
[1]=> "2013-02-12 01:44:03"
[2]=> "2013-02-05 16:25:07"
[3]=> "2013-01-29 02:00:15"
[4]=> "2013-01-27 18:33:45"
}
我想有办法提供一个日期(" 2013-02-04 14:11:16",例如),并有一个函数确定数组中最接近的匹配(这将是" 2013-02-05 16:25:07"在这种情况下)。
我很感激任何提示。谢谢! :)
答案 0 :(得分:18)
我可能没有最好的命名约定,但这里有。
我计算日期数组和给定日期之间的间隔。然后我做了一个排序,找到“最小的”差异。
$dates = array
(
'0'=> "2013-02-18 05:14:54",
'1'=> "2013-02-12 01:44:03",
'2'=> "2013-02-05 16:25:07",
'3'=> "2013-01-29 02:00:15",
'4'=> "2013-01-27 18:33:45"
);
function find_closest($array, $date)
{
//$count = 0;
foreach($array as $day)
{
//$interval[$count] = abs(strtotime($date) - strtotime($day));
$interval[] = abs(strtotime($date) - strtotime($day));
//$count++;
}
asort($interval);
$closest = key($interval);
echo $array[$closest];
}
find_closest($dates, "2013-02-18 05:14:55");
答案 1 :(得分:1)
如果我完全理解你的问题,那么这将解决你的问题。
<?php
$dates = array
(
'0' => "2013-02-18 05:14:54",
'1' => "2013-02-12 01:44:03",
'2' => "2013-02-05 16:25:07",
'3' => "2013-01-29 02:00:15",
'4' => "2013-01-27 18:33:45"
);
function closest($dates, $findate)
{
$newDates = array();
foreach($dates as $date)
{
$newDates[] = strtotime($date);
}
echo "<pre>";
print_r($newDates);
echo "</pre>";
sort($newDates);
foreach ($newDates as $a)
{
if ($a >= strtotime($findate))
return $a;
}
return end($newDates);
}
$values = closest($dates, date('2013-02-04 14:11:16'));
echo date('Y-m-d h:i:s', $values);
?>
答案 2 :(得分:0)
试试这个:
$date = array(
[0]=> "2013-02-18 05:14:54"
[1]=> "2013-02-12 01:44:03"
[2]=> "2013-02-05 16:25:07"
[3]=> "2013-01-29 02:00:15"
[4]=> "2013-01-27 18:33:45");
$baseDate = date_create('2009-10-11');
$count = count($date);
for($loop=0;$count>$loop;$loop++) {
$datetime = date_create($date[$loop]);
$interval = date_diff($baseDate, $datetime);
$newDate[$interval->format('%s')] = $date[$loop];
}
ksort($newDate);
foreach($newDate as $key=>$value) {
echo $value;
break;
}
您的第一个元素将是最接近的匹配日期。
注意:请在使用前进行测试。
答案 3 :(得分:0)
假设您的数组更大并且日期在2009-10-01
到2019-10-01
之间。现在让我们比较两种方法: looping-array approach
与b。 sorting-indexing-array approach
。
<?php
$period = new DatePeriod(
new DateTime('2009-10-01 00:00:00'),
new DateInterval('P3D'),
new DateTime('2019-10-01 00:00:00')
);
foreach($period as $date){
$dates[] = $date->format('Y-m-d');
};
$today = '2019-08-18 13:00:15';
function custom_sort($array){
sort($array);
return $array;
}
function nearest_date_key($array, $today){
//push today to the array, sort the array,
//find the nearest day value of the sorted array and return key
array_push($array, $today);
$sorted_dates = custom_sort($array);
$find_today_key = array_search($today, $sorted_dates);
$nearest_date = array_slice($sorted_dates, $find_today_key + 1, 1);
return array_search($nearest_date[0], $array);
}
function find_closest($array, $today)
{
//$count = 0;
foreach($array as $day)
{
//$interval[$count] = abs(strtotime($date) - strtotime($day));
$interval[] = abs(strtotime($today) - strtotime($day));
//$count++;
}
asort($interval);
$closest = key($interval);
return $closest;
}
$start = microtime(true);
$result_a = nearest_date_key($dates, $today);
$time_elapsed_secs_a = microtime(true) - $start;
$start = microtime(true);
$result_b = find_closest($dates, $today);
$time_elapsed_secs_b = microtime(true) - $start;
?>
打印结果得到(http://phptester.net/)
result time_elapsed
loop approach (a) 1203 0.00630
sorting index approach (b) 1203 0.00062
获得所花费的时间很长。我们将等待时间除以十
答案 4 :(得分:0)
这篇文章帮助我想到了解决类似问题的方法,所以我把它放在这里。
给定一组日期,我需要找到最接近的日期,早于或等于上周日。
这是我在不使用任何自定义函数的情况下所做的:
$all_dates = [
'20210328',
'20210321',
'20210314',
'20210307',
];
$last_sunday = date( 'Ymd', strtotime( date( 'Ymd' ) . 'last sunday')); //20210321
$latest_date_index;
foreach( $all_dates as $index => $date ) {
$date_obj = date_create_from_format( 'Ymd', $date );
$last_sunday_obj = date_create_from_format( 'Ymd', $last_sunday );
if ( $date_obj <= $last_sunday_obj ) {
$latest_date_index = $index;
break;
}
}
echo "latest date from array: $all_dates[$latest_date_index]";
echo "array of all past dates from array: " . var_dump(array_slice($all_dates, $latest_date_index));