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

mehany's avatar
Level 13

Why Carbon date is skipping one day of the month's days ?

What I want to achieve here is to start from the begging of the previous month, exactly at the begging of it ( on day one 12AM )

this does not provide the expected results

\Carbon\Carbon::now()->startOfMonth()->subMonths(1)->format('Y-m-d');

This instead works

  \Carbon\Carbon::now()->startOfMonth()->subMonths(1)->subDays(1)->format('Y-m-d');

where these date gets passed to the query below

 $list = $this->todo->between($start, $end)->get();

and here is the scopeBetween

public function scopeBetween($query, $from, $to) {
    $from   = Carbon::createFromFormat('Y-m-d', $from)->format('Y-m-d G:i:s');
    $to     = Carbon::createFromFormat('Y-m-d', $to)->format('Y-m-d G:i:s');
    $query->whereDate('date_of_transaction', '>=', $from);
    $query->whereDate('date_of_transaction', '<=', $to);
}

                

P.S

In my DB schema, I have field date_of_transaction as Date data type which is stored in this format '2015-09-01'

0 likes
6 replies
coder's avatar

try this

for start of the month

\Carbon\Carbon::now()->subMonth(1)->startOfMonth();

and for end of the month

\Carbon\Carbon::now()->subMonth(1)->endOfMonth();

Hope that will help .

mehany's avatar
Level 13

@coder same result.

this is \Carbon\Carbon::now() 2015-12-07 05:27:44

this is the output of \Carbon\Carbon::now()->subMonth(1)->startOfMonth() 2015-11-01 00:00:00
this is the output of \Carbon\Carbon::now()->subMonth(3)->startOfMonth() 2015-09-01 00:00:00

this is the output of \Carbon\Carbon::now()->startOfMonth()->subMonth(1) 2015-11-01 00:00:00
this is the output of \Carbon\Carbon::now()->startOfMonth()->subMonth(3) 2015-09-01 00:00:00

mehany's avatar
Level 13

Could this has to do with the date format and Eloquent way of searching dates?

thomaskim's avatar

@mehany What exactly is wrong with those results? Today is December 7th. The start of last month is November 1st.

mehany's avatar
Level 13

@thomaskim the above query scope does not return any transactions from the first of the month. For example I have records on 2015-09-01 and when I run

  $start .... , $end ....  // are Carbon instances '2015-09-01 00:00:00' , '2015-12-07 05:27:44'

  $list = $this->todo->between($start, $end)->get();

I get all transactions after '2015-09-01 00:00:00' even though in my query scope I requested also those transactions

$query->whereDate('date_of_transaction', '>=', $from);
$query->whereDate('date_of_transaction', '<=', $to);

So same apply for every first day of a requested month

coder's avatar

@mehany

i can see that you r not returning anything from your query scope. you are supposed to return something .

And one thing is that you can do it using a simple Eloquent query like this -

$startDate=\Carbon\Carbon::now()->subMonth(1)->startOfMonth()->format('Y-m-d');
$endDate=\Carbon\Carbon::now()->subMonth(1)->endOfMonth()->format('Y-m-d');
YOUR_MODEL::whereBetween('DATE_FIELD ', [$startDate, $endDate])->get()->toArray();

And if you are going with query scope then you can do the same by passing two additional parameter into your scope(not tried yet).

it should be like this --

public function scopeBetween($query, $from, $to) {
    $from   = Carbon::createFromFormat('Y-m-d', $from)->format('Y-m-d G:i:s');
    $to     = Carbon::createFromFormat('Y-m-d', $to)->format('Y-m-d G:i:s');
return    $query->whereBetween('date', [$from,$to ]);
}

Please or to participate in this conversation.