Search code examples
laravel-5php-carbon

Carbon::now() Giving Wrong Data


I am working with Carbon in Laravel.

Problem: I need to make a carbon date using Carbon::now()->month() function. For all other months, it is working fine. But when I am trying to make date for February 2021 it is always giving me the date of March 2021.

Below is My Function

function findStartEndDateOfAMonth($month, $year)
{
    //Here $month = 2, $year = 2021
    $days_in_month = cal_days_in_month(CAL_GREGORIAN, $month, $year);
    $start_time    = Carbon::now()->year($year)->month($month)->day(1)->hour(0)->minute(0)->second(0);

    $end_time      = Carbon::now()->year($year)->month($month)->day($days_in_month)->hour(23)->minute(59)->second(59);
    return [
      'start_time'    => $start_time,
      'end_time'      => $end_time,
      'days_in_month' => $days_in_month
    ];
} 

And here is the output:

{
  "code": 200,
  "message": "Successful",
  "time": {
   "start": {
      "date": "2021-03-01 00:00:00.000000",
      "timezone_type": 3,
      "timezone": "Asia/Dhaka"
    },
    "end": {
      "date": "2021-03-28 23:59:59.000000",
      "timezone_type": 3,
      "timezone": "Asia/Dhaka"
    }
  }
}

the similar result is giving for March (when I am giving $month = 3)

{
  "code": 200,
  "message": "Successful",
  "time": {
   "start": {
      "date": "2021-03-01 00:00:00.000000",
      "timezone_type": 3,
      "timezone": "Asia/Dhaka"
    },
    "end": {
      "date": "2021-03-31 23:59:59.000000",
      "timezone_type": 3,
      "timezone": "Asia/Dhaka"
    }
  }
}

I can't figure out the issue here.

Thanks in Advance.


Solution

  • Carbon::now()->year($year)->month($month)->day(1)->hour(0)->minute(0)->second(0);
    

    is buggy because it first changes year/month before changing the rest so it can overflow.

    First quick fix is:

    Carbon::now()->day(1)->year($year)->month($month)->hour(0)->minute(0)->second(0);
    

    But instead of mutating the date 6 times, you should use setDateTime to modify all at once:

    Carbon::now()->setDateTime($year, $month, 1, 0, 0, 0);
    

    Last question is: if you change all the values what's the point using now() why not simply create so you have no mutation at all?

    Carbon::create($year, $month, 1, 0, 0, 0);
    

    And for the record, you can use $start_time->daysInMonth getter on the object you created so you don't need to call cal_days_in_month