How to get First and Last Day of Previous Month with Carbon - Laravel
Asked Answered
A

7

74

I need First and Last Day of Previous Month using Carbon Library, what I have tried is as follows:

$firstDayofPreviousMonth = Carbon::now()->startOfMonth()->subMonth()->toDateString();
$lastDayofPreviousMonth = Carbon::now()->endOfMonth()->subMonth()->toDateString();

Result I'm getting is for$firstDayofPreviousMonth = '2016-04-01'(as current month is 5th(May)) and for $lastDayofPreviousMonth = '2016-05-01'.

I'm getting correct result for $firstDayofPreviousMonth, but it's giving me 30 days previous result, and giving me wrong result for $lastDayofPreviousMonth.

Can anyone help me out with this?

Agna answered 11/5, 2016 at 5:40 Comment(0)
D
90

Try this:

$start = new Carbon('first day of last month');
$end = new Carbon('last day of last month');
Darrondarrow answered 11/5, 2016 at 5:46 Comment(5)
Doesn't get the time as 00:00:00Kuhlman
As you see, he is trying to filter through some data. Your solution gives him wrong results. Please edit your answer to let him see exact results, then there will be no reason for down-vote.Kuhlman
I don't care about what you think, since asks this, he doesn't know what to do. So thanks to you he's probably filtering things wrong.Kuhlman
This is genuinely incorrect, been using this code with my company and it returns the wrong dates. In my experience Ozan is completely right, it works now not later. @Abu Sayem his answer worked properly for meRecurrence
This is the right answer. You can also combine with endOfDay() or startOfDay() to get 23:59:59 or 00:00:00Onitaonlooker
J
93

Just try this

$firstDayofPreviousMonth = Carbon::now()->startOfMonth()->subMonth()->toDateString();
$lastDayofPreviousMonth = Carbon::now()->subMonth()->endOfMonth()->toDateString();

Updated code, which is more accurate

$firstDayofPreviousMonth = Carbon::now()->startOfMonth()->subMonthsNoOverflow()->toDateString();

$lastDayofPreviousMonth = Carbon::now()->subMonthsNoOverflow()->endOfMonth()->toDateString();

@kenfai Thanks

Jigger answered 11/5, 2016 at 5:51 Comment(5)
This is the definitely the best, as it starts at 00:00 and ends at 23:59:59. The accepted solution doesn't take time into account and might produce unreliable results.Encyclopedia
I just want to point out, due to PHP DateTime overflow issue, you may want to use subMonthNoOverflow() instead. More discussion here: github.com/briannesbitt/Carbon/issues/428Osgood
@Osgood Thanks I have updated the code sampleJigger
An thank you! because I had the 31 day of month issueSewage
I was using laravel 5.6. so when i use the updated solution the i got an error that was telling you have to provide value in the method subMonthsNoOverflow() . i put 1 to get my result.Featherveined
D
90

Try this:

$start = new Carbon('first day of last month');
$end = new Carbon('last day of last month');
Darrondarrow answered 11/5, 2016 at 5:46 Comment(5)
Doesn't get the time as 00:00:00Kuhlman
As you see, he is trying to filter through some data. Your solution gives him wrong results. Please edit your answer to let him see exact results, then there will be no reason for down-vote.Kuhlman
I don't care about what you think, since asks this, he doesn't know what to do. So thanks to you he's probably filtering things wrong.Kuhlman
This is genuinely incorrect, been using this code with my company and it returns the wrong dates. In my experience Ozan is completely right, it works now not later. @Abu Sayem his answer worked properly for meRecurrence
This is the right answer. You can also combine with endOfDay() or startOfDay() to get 23:59:59 or 00:00:00Onitaonlooker
D
20

With this ... the date start init on 00:00 and date end finish in 23:59

$start = new Carbon('first day of last month');
$start->startOfMonth();
$end = new Carbon('last day of last month');
$end->endOfMonth();
Deflate answered 15/5, 2017 at 0:25 Comment(1)
This should be correct answer, because it compares time as well.Asuncion
J
12

To specifically answer your question as to why you're getting the wrong result for $lastDayofPreviousMonth.

Lets break down this statement in your example:

Carbon::now()->endOfMonth()->subMonth()->toDateString();
// Carbon::now() > 2016-05-05
// ->endOfMonth() > 2016-05-31
// ->subMonth() > 2016-04-31 // Simply takes 1 away from 5.

This leaves us with an invalid date — there is no 31st of April. The extra day is simply added on to the last valid date (2016-04-30 + 1) which rolls the date into May (2016-05-01).

As previously mentioned to be sure this never happens always reset the date to the 1st of the month before doing anything else (as every month has a 1st day).

$lastDayofPreviousMonth = Carbon::now()->startofMonth()->subMonth()->endOfMonth()->toDateString();
// Carbon::now() > 2016-05-05
// ->startofMonth() > 2016-05-01 00:00:00
// ->subMonth() > 2016-04-01 00:00:00
// ->endOfMonth() > 2016-04-30 23:59:59
Jura answered 26/7, 2017 at 9:27 Comment(0)
I
5

There is currently a bug within Carbon when using the method

Carbon::now()->startOfMonth()->subMonth()->endOfMonth()->toDateTimeString();

The bug results in returning the last day as 30 for those months that have 31 days.

IE - if you are in March and you run the above call it will return 2017-03-30 and not 2017-03-31 as you would expect.

As I was doing a between dates operation I ended up using..

Carbon::now()->startOfMonth()->subSeconds(1)->toDateTimeString();

This ended up with the correct date dateTimeString for those days that end on the 31st.

Ingathering answered 13/4, 2017 at 21:18 Comment(0)
U
5

Another solution is using Carbon method subMonthNoOverflow():

$lastDayofPreviousMonth = Carbon::now()->subMonthNoOverflow()->endOfMonth()->toDateString();

Found it here when run into 31 day of month issue: https://github.com/briannesbitt/Carbon/issues/627

Up answered 30/10, 2019 at 23:21 Comment(0)
P
1

This works for me.

$firstDayofPreviousMonth = Carbon::now()->startOfMonth()->subMonth()->toDateTimeString(); // 2021-08-01 00:00:00
$lastDayofPreviousMonth = Carbon::now()->endOfMonth()->subMonth()->toDateTimeString(); // 2021-08-31 23:59:59

Use of single $date variable

$date = Carbon::now();

$firstDayofPreviousMonth = $date->startOfMonth()->subMonth()->toDateTimeString(); // 2021-08-01 00:00:00

$lastDayofPreviousMonth = $date->endOfMonth()->toDateTimeString(); // 2021-08-31 23:59:59
Psia answered 10/9, 2021 at 9:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.