Carbon::parse('last month') gives 1st of the current month

Created on 29 Mar 2021  路  4Comments  路  Source: briannesbitt/Carbon


Hello,

I encountered an issue with the following code:

echo Carbon::parse('last month');

Carbon version: 2.43.0

PHP version:
PHP 7.4.10 (cli) (built: Sep 10 2020 13:50:32) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Xdebug v3.0.3, Copyright (c) 2002-2021, by Derick Rethans

I expected to get:

2021-02-01

But I actually get:

2021-03-01

Exact Carbon object:
Carbon\Carbon @1614596217 {#4686
     date: 2021-03-01 10:56:57.406382 UTC (+00:00),
   }

Thanks!

php bug

All 4 comments

I've been having a similar issue, Carbon::now()->subMonth() returned 1st March, when now is 29th March.

But I've realised what my issue is, and it's the same as yours here.

Assuming this result is from today (29th March), it's becuase Feburary had 28 days this year, so it's adding the remaining 1 day, tomorrow it would return 2nd March, adding the 2 days difference.

This is becuase "last month" is asking for this day (29th) of last month, which today, doesn't exist. This is the same reason my Carbon::now->subMonth() is returning 1st March.

What you want is Carbon::parse('first day of last month')

Hello,

As you can see here:
https://3v4l.org/8Q73S

Pure PHP gives you the same output.

$date = new DateTime('last month');

echo $date->format('Y-m-d');

As Carbon extends DateTime it inherits the bug from native PHP. There no much we can do without breaking something else.

Proper work-around is as @jimmy718 suggests: Carbon::parse('first day of last month')

Same for Carbon::now()->subMonth() you can see new DateTime('now - 1 month') would have the same overflow issue.

You can also do \Carbon\Carbon::now()->startOfMonth()->subMonths($i) for anyone doing this in a loop.

You can also do \Carbon\Carbon::now()->startOfMonth()->subMonths($i) for anyone doing this in a loop.

Yes, this is the workaround we found. It works just fine.

Was this page helpful?
0 / 5 - 0 ratings