Carbon is my favorite date manipulation class since the day one I introduced with Laravel. It simplifies working with dates and times, making tasks like date manipulation a breeze. However, there can be some confusion when using certain Carbon functions, like what I have been doing today.
The Problem
I wanted to manipulate using Carbon to get both the start and end of the day. Naturally, I reached for startOfDay()
and endOfDay()
functions, thinking they will do the job perfectly.
$dateCarbon = Carbon::parse($date);
$start = $dateCarbon->startOfDay(); // Outputs 2023-09-27 00:00:00
$end = $dateCarbon->endOfDay(); // Outputs 2023-09-27 00:00:00 (Expected: 2023-09-27 23:59:59)
Surprisingly, both $start
and $end
have the same value of 2023-09-27 00:00:00
. This is not what I expected! The endOfDay()
should give me the end of the day, which is typically 23:59:59.
The Explanation
The reason behind this behavior lies in how Carbon manages objects. When I call endOfDay()
on a Carbon object, it modifies the same object instance and sets the time to midnight (00:00:00) of the same day. This happens because Carbon, by default, modifies the original object rather than creating a new one.
The Solution
After several searches and chats (with GPT), I found out that I need to make a copy of the Carbon object.
That was why my result always points the same value.
Here, I can tweak one instance for the start of the day and another for the end of the day without messing with the original date.
$dateCarbon = Carbon::parse($date);
$start = $dateCarbon->startOfDay();
$end = $dateCarbon->copy()->endOfDay(); // Now, $end will be 2023-09-27 23:59:59
By using $dateCarbon->copy()
before calling endOfDay()
, I ensure that I’m working with a separate instance of the Carbon object. This prevents unintended changes to the original date.