How to get closest date compared to an array of dates in PHP

前端 未结 4 1208
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-29 06:08

This post almost answered this question for me, but I have a specific need and didn\'t find what I sought there. This lies right outside my experience; couldn\'t quite wrap

相关标签:
4条回答
  • 2020-11-29 06:29

    I may not have the best naming conventions, but here goes.

    I calculate the intervals between the array of dates and the given date. I then do a sort, to find the "smallest" difference.

    $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");
    
    0 讨论(0)
  • 2020-11-29 06:40

    If I understand your question perfectly then this will solve your problem.

    Tested Code

    <?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);
    ?>
    
    0 讨论(0)
  • 2020-11-29 06:43

    Just try this:

    $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;
    }
    

    Your first element will the the closest match date.

    Note: Please test it before you use.

    0 讨论(0)
  • 2020-11-29 06:52

    Suppose your array is bigger and that you have dates over the period 2009-10-01 to 2019-10-01. Lets now compare two approach: a. looping-array approach vs 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;
    ?>
    

    Printing the results gives (http://phptester.net/)

                                result  time_elapsed
    loop approach (a)           1203    0.00630   
    sorting index approach (b)  1203    0.00062
    

    Which is a huge time elapsed gain. We divided by ten the waiting time

    0 讨论(0)
提交回复
热议问题