【问题标题】:How to get closest date compared to an array of dates in PHP与PHP中的日期数组相比,如何获得最接近的日期
【发布时间】:2013-02-22 04:15:00
【问题描述】:

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" 在这种情况下)。

如果有任何提示,我将不胜感激。谢谢! :)

【问题讨论】:

    标签: php date strtotime


    【解决方案1】:

    我可能没有最好的命名约定,但这里是。

    我计算日期数组和给定日期之间的间隔。然后我进行排序,找出“最小”的差异。

    $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");
    

    【讨论】:

    • 我最终再次查看了我的代码并制定了解决方案。当我回来检查这个线程时,我们的代码几乎相同!将此标记为解决方案,因为这正是我最终要做的。
    • 啊哈!当您提出问题时,您应该更频繁地检查 SO :)
    • 我应该而且通常会这样做。似乎是罕见的失误。另外,我实际上注意到您的代码只是一个触摸清洁器,所以我采用了它。谢谢!
    • 如果有 2 个日期具有相同的差异怎么办?
    【解决方案2】:

    假设您的数组更大,并且您在2009-10-012019-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
    

    这是一个巨大的时间流逝增益。我们除以十的等待时间

    【讨论】:

      【解决方案3】:

      如果我完全理解您的问题,那么这将解决您的问题。

      测试代码

      <?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);
      ?>
      

      【讨论】:

      • 最近的上一个日期呢?我们如何从这个数组中找到最近的上一个日期/
      【解决方案4】:

      试试这个:

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

      您的第一个元素将是最接近的匹配日期。

      注意:请在使用前进行测试。

      【讨论】:

      • 非常感谢您的帮助!测试后,“echo $value;”似乎总是返回数组中的最后一个结果。
      • @Jon 那是我在那里休息的地方。
      • @SureshKamrushi 无论我们是否更改日期,您的代码始终以 2013-02-12 01:44:03 作为输出。
      【解决方案5】:

      这篇文章帮助我想出了解决我类似问题的方法,所以我把它放在这里了。

      给定一个日期数组,我需要找到最接近上周日之前或等于的日期。

      这是我在不使用任何自定义函数的情况下所做的:

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

      【讨论】:

        猜你喜欢
        • 2022-01-08
        • 2015-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-19
        • 2019-03-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多