PHP:在Array中查找下一个最接近的月份

Given an array which looks like this:

$months = array("mar","jun","sep","dec");

And the current month:

$current_month = date("m");

Is there a way to find the next closest month to the current month?

For example:

  • if the current month is May, the result should be 'jun'
  • if the current month is April, the result should be 'jun'
  • if the current month is March, the result should be 'mar'
  • if the current month is October, the result should be 'dec'

Assuming that you want to get the last month of the current quarter, you could do it like this:

$monthName = ["mar", "jun", "sep", "dec"][floor((date('n') - 1) / 3)];

Just need to add all the months and print the position of the next moth.

<?php
$months = array("jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec");
$current_month = date("m");

// The next moth must be the current month + 1 but as the index start from 0 we dont need to add + 1
// So we print 
echo $months[ $current_month % count($months)]; 

As the array position start from 0 you don't need to add +1

I like @Rizier123's solution so I thought I'd write up an implementation.

First, let's convert the months array into numerical values which represent the month. We're going to preserve the text as the key to make the matching process easier at the end. If you have control over those months then it's quite simple:

$months = [ 'mar' => 3, 'jun' => 6, 'sep' => 9, 'dec' => 12];

If you don't have control over the array you'll need to run it through array_map() and use date to convert:

$month_keys = $months;

$months = array_map( function( $month ) {
    return date( 'm', strtotime( $month ) );
}, $months );

$months = array_combine( $month_keys, $months );

Then let's find the next closest value in the array:

$closest_month = null;

foreach ( $months as $month_text => $month_num ) {
    if ( $current_month <= $month_num ) {
        $closest_month = $month_text;
        break;
    }
}

$closest_month should now match all of the conditions set out in your question.