Get the last 12 months in PHP

后端 未结 5 1676
醉话见心
醉话见心 2020-12-14 16:46

So here is an interesting problem I learned today.

I need to populate an array with the last 12 months, starting with the past month. So in August 2011, the last 12

相关标签:
5条回答
  • 2020-12-14 17:02

    I'd like to propose an alternative solution using DatePeriod instead.

    There are a number of caveats to watch out for here. For one, you don't want things like Timezone information, or day/time information to get in your way. You're only interested in the month. So we can normalize some of this information to prevent complications like overflows and daylight savings complications, etc... Since you could easily fall into this trap only on specific dates/times when these rare events occur.

    $start = new DateTime;
    $start->setDate($start->format('Y'), $start->format('n'), 1); // Normalize the day to 1
    $start->setTime(0, 0, 0); // Normalize time to midnight
    $start->sub(new DateInterval('P12M'));
    $interval = new DateInterval('P1M');
    $recurrences = 12;
    
    foreach (new DatePeriod($start, $interval, $recurrences, true) as $date) {
        echo $date->format('F, Y'), "\n"; // attempting to make it more clear to read here
    }
    

    Output:

    February, 2019
    March, 2019
    April, 2019
    May, 2019
    June, 2019
    July, 2019
    August, 2019
    September, 2019
    October, 2019
    November, 2019
    December, 2019
    January, 2020
    
    0 讨论(0)
  • 2020-12-14 17:05

    I think this will work:

    $this_month = date("n", time());
    $this_year = date("Y", time());
    $months_array = array();
    for ($i = $this_month - 1; $i > ($this_month - 13); $i--) {
        echo "$i<br>";
        if ($i < 1) {
            $correct_month_number = $i + 12;
            $months_array[] = array($correct_month_number, $this_year - 1);
        }
        else {
            $months_array[] = array($i, $this_year);
        }
    }
    echo "<pre>"; var_dump($months_array); echo "</pre>";
    

    The data types are a little loose, but this gets the job done. The nice thing about this is that it only calls the date() function for the current month and year, once. The rest of the logic is just simple math. No need to worry about the length of each month.

    Then you can use the $months_array array to build whatever you need.

    0 讨论(0)
  • 2020-12-14 17:09

    It's because not every month has a 31st. So strtotime() is advancing to the next month. i.e. 4/31 = 5/1.

    You'd be better off using mktime() for this as it's dumber than strtotime().

    UPDATE

    To take advantage of a smart function like strtotime() and avoid tracking the year for mktime(), the following is my suggestion:

    $month = time();
    for ($i = 1; $i <= 12; $i++) {
      $month = strtotime('last month', $month);
      $months[] = date("r", $month);
    }
    print_r($months);
    

    Adjust logic and optimize as you see fit.

    0 讨论(0)
  • 2020-12-14 17:10

    I'm sure someone has a more elegant solution, but you could start counting backwards from the 1st of this month.

    for ($i = 1; $i <= 12; $i++) {
        $months[] = date("Y-m%", strtotime( date( 'Y-m-01' )." -$i months"));
    }
    
    0 讨论(0)
  • 2020-12-14 17:12

    The joys of different month lengths. strtotime is being literally, and taking 'Aug 31' and tryinn to make "Sep 31", which doesn't exist. So you end up with Oct 1 or something. A safer approach is this:

    for ($i = 1; $i <= 12; $i++) {
        $months[] = date("Y-m%", mktime(0, 0, 0, $i, 1, 2011));
    }
    

    strtotime is magical sometimes, but it's not reliable and certainly not "fast".

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