​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.

Mohammad Morakabati
7 min readJun 21, 2023
DateTime Handling in Laravel by Carbon
DateTime Handling in Laravel by Carbon

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.

List of methods for modifying Datetime in carbon

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:

Definition of the now() function in the Laravel framework
Definition of the now() function in the Laravel framework

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.

The main place of inheritance from the Carbon in Laravel
The main place of inheritance from Carbon in Laravel

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?

Definition of the Carbon class in the Carbon package
Definition of the Carbon class in the Carbon package

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.

now() function in Carbon package
now() function in the Carbon package

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.

--

--

Mohammad Morakabati
Mohammad Morakabati

Written by Mohammad Morakabati

Back-End Developer (PHP & Laravel)

No responses yet