Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

garrettmassey's avatar

Carbon is giving the wrong month when creating new instance.

I am working on a helper class to get quarterly reporting dates, and I am using Carbon to do some of the date calculations. For some reason, when the quarter is supposed to be Q2 (October 1 - December 31, what we are currently in), the 'start date' for the quarter is listed as September 1st.

class Quarter
{
    public string $quarter;
    public string $fiscalYear;
    public Carbon $startDate;
    public Carbon $endDate;
    public string $startMonth;
    public string $endMonth;
    public Carbon $currentDate;
    public int $daysInQuarter;

    public function __construct(Carbon $currentDate = null)
    {
        if ($currentDate === null) {
            $currentDate = Carbon::now();
        }
        //determine what quarter we are in based on the current date
        $this->currentDate = $currentDate;
        $this->quarter = self::determineQuarter($currentDate)['quarter'];
        $this->fiscalYear = self::determineQuarter($currentDate)['year'];
        $this->startDate = self::determineQuarter($currentDate)['startDate'];
        $this->endDate = self::determineQuarter($currentDate)['endDate'];
        $this->startMonth = self::determineQuarter($currentDate)['startMonth'];
        $this->endMonth = self::determineQuarter($currentDate)['endMonth'];
        $this->daysInQuarter = $this->startDate->diffInDays($this->currentDate);
    }

    private static function determineFiscalYear(Carbon $date): int
    {
        //if the date is before July 1st, the fiscal year will be the current calendar year
        if ($date->month < 7) {
            return $date->year;
        } else {
            //if the date is after June 30th, the fiscal year will be the next calendar year
            return $date->year + 1;
        }
    }

    private static function determineQuarter(Carbon $date): array
    {
        $fiscalYear = self::determineFiscalYear($date);
        //if the date is between July 1st and September 30th, the quarter will be Q1
        //the fiscal year is always one year ahead of the calendar year.
        //therefore, if the date is between July 1st and December 31st, the
        //fiscal year will be the next calendar year.
        if ($date->month >= 7 && $date->month <= 9) {
			$fiscalYear = $fiscalYear - 1;
            return [
                'quarter' => 'Q1',
                'year' => $fiscalYear + 1,
                'startDate' => new Carbon('first day of July ' . $fiscalYear),
                'endDate' => new Carbon('last day of September ' . $fiscalYear),
                'startMonth' => 'July',
                'endMonth' => 'September',
            ];
        }
        //if the date is between October 1st and December 31st, the quarter will be Q2
        if ($date->month >= 10 && $date->month <= 12) {
			$fiscalYear = $fiscalYear - 1;
            return [
                'quarter' => 'Q2',
                'year' => $fiscalYear + 1,
                'startDate' => new Carbon('first day of October ' . $fiscalYear),
                'endDate' => new Carbon('last day of December ' . $fiscalYear),
                'startMonth' => 'October',
                'endMonth' => 'December',
            ];
        }
        //if the date is between January 1st and March 31st, the quarter will be Q3
        if ($date->month >= 1 && $date->month <= 3) {
            return [
                'quarter' => 'Q3',
                'year' => $fiscalYear,
                'startDate' => new Carbon('first day of January ' . $fiscalYear),
                'endDate' => new Carbon('last day of March ' . $fiscalYear),
                'startMonth' => 'January',
                'endMonth' => 'March',
            ];
        }
        //if the date is between April 1st and June 30th, the quarter will be Q4
        if ($date->month >= 4 && $date->month <= 6) {
            return [
                'quarter' => 'Q4',
                'year' => $fiscalYear,
                'startDate' => new Carbon('first day of April ' . $fiscalYear),
                'endDate' => new Carbon('last day of June ' . $fiscalYear),
                'startMonth' => 'April',
                'endMonth' => 'June',
            ];
        }
    }
}

Above is my class code for Quarter. I have also tried making the carbon instance work like this:

'startDate' => Carbon::create($fiscalYear, 10, 01);

and that doesn't seem to work for Q2.

Every time I ddd($quarter) in my code using today's date to create the instance of the Quarter class, it shows the start date of Q2 as September 1st instead of October 1st, and I have no idea why.

App\Helpers\Quarter {#1825 ▼
  +quarter: "Q2"
  +fiscalYear: "2023"
  +startDate: Carbon\Carbon @1662012000 {#1617 ▼
    #endOfTime: false
    #startOfTime: false
    #constructedObjectId: "000000004112c8a60000000067d9927f"
    #localMonthsOverflow: null
    #localYearsOverflow: null
    #localStrictModeEnabled: null
    #localHumanDiffOptions: null
    #localToStringFormat: null
    #localSerializer: null
    #localMacros: null
    #localGenericMacros: null
    #localFormatFunction: null
    #localTranslator: null
    #dumpProperties: array:3 [▶]
    #dumpLocale: null
    #dumpDateProperties: null
    date: 2022-09-01 00:00:00.0 America/Denver (-06:00)
  }
  +endDate: Carbon\Carbon @1672470000 {#1616 ▶}
  +startMonth: "October"
  +endMonth: "December"
  +currentDate: Carbon\Carbon @1667926895 {#1771 ▶}
  +daysInQuarter: 38
}

The way I am getting the current quarter is like this:

$currentQuarter = new Quarter(Carbon::now());
ddd($currentQuarter);

I don't know what's wrong with my code that it insists the startDate of Q2 is September 1st, but that is not correct.

0 likes
0 replies

Please or to participate in this conversation.