Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getting all months between 2 dates

Tags:

php

php-carbon

I created a function that returns an array containing each month, starting from a supplied carbon date and ending on the current date.

Although the function is doing what it is supposed to do, it looks hideous. Clearly my programming skills arent yet what they're supposed to be. Surely there must be a better way to achieve what i want.

My code looks like this:

    class DateUtilities {
    protected $months = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];

    public function getMonthListFromDate(Carbon $date)
    {
        $monthArray = array();
        $today = Carbon::today();

        $currentYear = $today->copy()->format('Y');
        $currentMonth = strtolower($today->copy()->format('F'));

        $startYear = $date->copy()->format('Y');
        $startMonth = strtolower($date->copy()->format('F'));

        for($i = $startYear; $i <= $currentYear; $i ++) {
            foreach($this->months as $monthIndex => $month) {
                if (($monthIndex >= array_search($startMonth, $this->months) && $i == $startYear) ||
                    ($monthIndex <= array_search($currentMonth, $this->months) && $i == $currentYear) ||
                    ($i != $startYear && $i != $currentYear)) {
                    $formattedMonthIndex = ($monthIndex + 1);

                    if($formattedMonthIndex < 10) {
                        $monthArray['0' . $formattedMonthIndex . '-' . $i] = $month . ' ' . $i;
                    } else {
                        $monthArray[$formattedMonthIndex . '-' . $i] = $month . ' ' . $i;
                    }
                }
            }
        }

        return $monthArray;
    }
}

and the result is:

array:25 [▼
  "03-2013" => "march 2013"
  "04-2013" => "april 2013"
  "05-2013" => "may 2013"
  "06-2013" => "june 2013"
  "07-2013" => "july 2013"
  "08-2013" => "august 2013"
  "09-2013" => "september 2013"
  "10-2013" => "october 2013"
  "11-2013" => "november 2013"
  "12-2013" => "december 2013"
  "01-2014" => "january 2014"
  "02-2014" => "february 2014"
  "03-2014" => "march 2014"
  "04-2014" => "april 2014"
  "05-2014" => "may 2014"
  "06-2014" => "june 2014"
  "07-2014" => "july 2014"
  "08-2014" => "august 2014"
  "09-2014" => "september 2014"
  "10-2014" => "october 2014"
  "11-2014" => "november 2014"
  "12-2014" => "december 2014"
  "01-2015" => "january 2015"
  "02-2015" => "february 2015"
  "03-2015" => "march 2015"
]

Can anyone help me improve this code?

EDIT:

After the great tips i ended up with the following:

class DateUtilities {

public function getMonthListFromDate(Carbon $start)
{
    $start = $start->startOfMonth();
    $end   = Carbon::today()->startOfMonth();

    do
    {
        $months[$start->format('m-Y')] = $start->format('F Y');
    } while ($start->addMonth() <= $end);

    return $months;
}

}

Thank you for the help guys!!

like image 274
vincent Avatar asked Mar 17 '15 18:03

vincent


People also ask

How do I get months between two dates in SQL?

MONTHS_BETWEEN returns number of months between dates date1 and date2 . If date1 is later than date2 , then the result is positive. If date1 is earlier than date2 , then the result is negative. If date1 and date2 are either the same days of the month or both last days of months, then the result is always an integer.

How do I calculate months between two dates in Excel?

Use the DATEDIF function method if you want to get the total number of completed months in between two dates (it ignores the start date) Use the YEARFRAC method when you want to get the actual value of months elapsed between tow dates.

How do I get the month between two dates in Python?

Use the relativedelta. months + relativedelta. years * 12 formula to get the total months between two dates.


2 Answers

Late to this party, but worth adding that Carbon already has this covered. Using CarbonPeriod would reduce the whole class to ...

use Carbon\Carbon;
use Carbon\CarbonPeriod;

class DateUtilities
{
    public function getMonthListFromDate(Carbon $start)
    {
        foreach (CarbonPeriod::create($start, '1 month', Carbon::today()) as $month) {
            $months[$month->format('m-Y')] = $month->format('F Y');
        }
        return $months;
    }
}
like image 161
petercoles Avatar answered Sep 21 '22 01:09

petercoles


With DateTime this could be easily achieved.

  1. Create a datetime object for each start and end date
  2. Setup an interval of 1 month
  3. Get a set of date beetween the start date and the end date with 1 month interval

Example :

public function getMonthListFromDate(Carbon $date)
{
    $start    = new DateTime(); // Today date
    $end      = new DateTime($date->toDateTimeString()); // Create a datetime object from your Carbon object
    $interval = DateInterval::createFromDateString('1 month'); // 1 month interval
    $period   = new DatePeriod($start, $interval, $end); // Get a set of date beetween the 2 period

    $months = array();

    foreach ($period as $dt) {
        $months[] = $dt->format("F Y");
    }

    return $months;
}

See it in action : http://3v4l.org/smS3N

like image 32
BentoumiTech Avatar answered Sep 19 '22 01:09

BentoumiTech