DateTime Handling in Laravel by Carbon
Using the Carbon package in PHP and Laravel results in more readable code that makes the complexity of working with date & time disappear for developers.
To work with date and time in PHP and Laravel, we can use PHP functions and classes, but as you know, this method has complications, and that’s why many developers use another package called Carbon.
The Carbon package is actually a PHP DateTime
extension that inherits from the DateTime
class in the background. Using this package, simpler and more expressive codes are generated, and readability and the ability to save date and time are added to the project.
The Laravel framework uses Carbon by default, but the documentation doesn’t say much about it, so we need to look into it and understand how to manage the date and time in Laravel using Carbon.
What does carbon do?
In short, interacting with date, time and timezone becomes easier with the help of Carbon, namely:
- Construct datetime
- Datetime conversion between different timezones
- Making changes in datetime (adding and subtracting)
- Calculate the difference between two time intervals
- Convert datetime to suitable and understandable text for humans
Please see the code snippet below to see the potential of carbon in creating simplicity, beauty, and readability in the project:
$trialExpires = now()->addDays(30);
Retrieve Datetime
If you are using Laravel, you do not need to install Carbon because, as I said, it is installed by default with Laravel and is available to developers, and all you need to do is invoke Carbon as follows:
use Illuminate\Support\Carbon;
According to this pull request, the above code wraps the original Carbon package into a container that adds macroable functionality to Carbon in Laravel. Of course, you can still use the Carbon package directly:
use Carbon\Carbon;
We can instantiate it wherever we need it:
$current = new Carbon();
$newYear = new Carbon('first day of January 2024');
The helper functions now()
and today()
in Laravel uses Carbon, and of course, we can call some popular methods statically:
$yesterday = Carbon::yesterday();
$today = Carbon::today();
$current = Carbon::now();
$londonCurrentTime= Carbon::now('Europe/London');
$tomorrow = Carbon::tomorrow();
We can set the timezone for the above methods, but if we don’t, the default timezone will be UTC+0, and if we want to create a date and time based on the arguments, there are special static methods for that:
Carbon::createFromDate($year, $month, $day, $tz); // Creating Date
Carbon::createMidnightDate($year, $month, $day, $tz); // Create date based on 00:00
Carbon::createFromTime($hour, $minute, $second, $tz); // Create Time
Carbon::createFromTimeString("$hour:$minute:$second", $tz); // Create Time from string
Carbon::create($year, $month, $day, $hour, $minute, $second, $tz); // Create Date & Time
We can send the above arguments as null
and Carbon will consider the current time specification for that argument.
Using the parse method, we can directly define the date it takes to create a Carbon object:
$lastDayOfFeb2021 = Carbon::parse('last day of February 2021');
Also using this method we can create a carbon object based on the timestamp entered:
$lastDayOfFeb2021 = $Carbon::parse(1614470400);
Modify Datetime
Getting the date is not the only thing we can do with the Carbon package, we can also modify the date we want with this package.
now()->addDays(3);
now()->subDays(3);
Be sure to visit this section of the Carbon documentation to see the full list of methods we need to modify the date and time.
Use Getters and Setters
When we use the Carbon package, we as developers have our hands full, i.e. we can use any method to meet the requirements. For example, in addition to the above methods, we can use getters and setters to read and change the date.
$datetime = Carbon::now();
$dt->year = 2024;
echo $dt->year;
If you do not like the above way, that’s no problem, check out the following way:
$datetime = Carbon::now();
$datetime ->year(2024);
echo $datetime ->year();
We can even use these methods in a chain:
$dt= Carbon::now();
$dt->year(2024)->month(1)->day(7)->hour(20)->minute(30)->second(40)->toDateTimeString();
If you think that Getters and Setters are the answer to your needs, you should look at the relevant sections in the Carbon documentation. (Getters in Carbon and Setters in Carbon)
Determine the output format
If you want to have an output that is readable by humans, Carbon provides a number of standard methods to help you do that:
$dt = Carbon::create(1975, 12, 25, 14, 15, 16);
echo $dt->toDateString(); // 1975-12-25
echo $dt->toTimeString(); // 14:15:16
echo $dt->toDateTimeString(); // 1975-12-25 14:15:16
echo $dt->toFormattedDateString(); // Dec 25, 1975
echo $dt->toFormattedDayDateString(); // Thu, Dec 25, 1975
echo $dt->toDayDateTimeString(); // Thu, Dec 25, 1975 2:15 PM
If none of the above methods gives the desired output, that’s not a problem, because the format()
method can still be used.
$dt = Carbon::create(1975, 12, 25, 14, 15, 16);
echo $dt->format('l jS \\of F Y h:i:s A'); // Thursday 25th of December 1975 02:15:16 PM
If you have a question about where the values in the format()
method come from, you should take a look at this section of the PHP documentation on date and time formatting.
Calculate the difference
With Carbon, we can measure the difference between 2 Datetimes in the desired unit, e.g. in days or hours:
$now = Carbon::now();
$future = Carbon::now()->addHours(6);
echo $now->diffInHours($future);
The output of the above code is 6
, but let’s continue with a more interesting example:
$dtOttawa = Carbon::createMidnightDate(2021, 1, 1, 'America/Toronto');
$dtVancouver = Carbon::createMidnightDate(2021, 1, 1, 'America/Vancouver');
echo $dtOttawa->diffInHours($dtVancouver);
echo $dtVancouver->diffInHours($dtOttawa);
If we need an output to be clearer to humans, diffForHumans()
is our answer:
echo Carbon::now()->subDays(5)->diffForHumans(); // 5 days ago
Integration in Laravel
The main point of integrating the Carbon package into the Laravel framework is to convert the value stored in the database into the Carbon object, which has become much easier in Laravel with the help of the casting concept:
class Post extends Model {
protected $casts = [
'published_at' => 'datetime',
];
}
Note that created_at
and updated_at
columns are converted to Carbon Object by default in Laravel and we only need to think of other columns that need to be converted to date or datetime
.
Journey into the depths of Laravel
To better understand the integration of Laravel and Carbon, it is better to go deep into the Laravel code, but before that, if we take a look at the Laravel documentation, we will come across the now()
and tomorrow()
functions. These functions basically use Carbon, and as we can see in the Laravel code in Illuminate\Foundation\helpers.php
, they return a Carbon object:
In this function, there is Date
class that is called at the beginning of the file:
use Illuminate\Support\Facades\Date;
And if we go to the file where Date
class is defined, we can see that the main class is determined based on DEFAULT_FACADE
in the resolveFacadeInstance
method, which is called DateFactory
.
Now it is necessary to enter the DateFactory
in the path Illuminate/Support/DateFactory.php
to find out how the now()
is defined, but if we check the DateFactory
completely we will find that there is no method called now()
, so in this situation the magic method __call()
would be executed.
In __call()
, there is a value of $dateClass
in which Illuminate\Support\Carbon
is defined, and it checks if the method (e.g. now()
) searched for is present in Illuminate\Support\Carbon
or if it is defined as a macro. If the wanted method exists, it will be called and executed.
According to the obtained results, we need to go to the Illuminate/Support/Carbon.php
file, and there we will see that this class is actually a wrapper for its parent class(Carbon
class), and allows us to do things like define a macro.
Now let us go to the Carbon package, i.e. where the Carbon class is defined, and there we see that the Carbon
class inherits from the DateTime
class in PHP, but if you look closely, you will notice that there are no other methods, and the question arises where the rest of the methods were really defined?
Well, we looked for a method like now()
in this file and we saw that there is no more method in this class and we know that there is no method named now()
in the DateTime
class, but if we look more closely, we can see that in this class, a trait
with The name Date
is used, it is possible that our methods are defined there.
We enter the desired trait
, namely Date, and see that there is no now()
function there, but various trait
are use
in it, and the name of one of these trait
is Creator
, so it is better to enter it directly.
This is the end of our wonderful journey, where our desired methods like now()
or tomorrow()
are defined.
As we found out, the Carbon\Carbon
class in Laravel is wrapped by Illuminate\Support\Carbon
, which adds macroable functionality for date and time in Laravel. (Pull request for this feature)
We have reached the end of the article and familiarized ourselves with the main features of the Carbon package. We can use it in most projects with confidence and we were able to understand its integration with Laravel by delving into the depths of Carbon and Laravel.
Since this package is very extensive, its documentation should not be neglected at all, and as developers we should be able to explore the documentation for the needs of the project and extract the desired requirements from it.