Skip to content

Date and time handling ​

1. Standard datetime format ​

  • Use ISO8601 for both frontend and backend when exchanging datetime data
  • Example: 2025-05-02T15:30:00+07:00

2. Register CarbonImmutable globally ​

php
Date::use(CarbonImmutable::class);

3. Use the application timezone by default ​

Laravel sets PHP's default timezone from config('app.timezone') during bootstrap. Do not pass that same config value to Carbon methods such as now(), parse(), or createFromFormat(). Pass a timezone only when the operation explicitly needs a timezone different from the application's default.

4. Type hinting datetime parameters ​

  • Use CarbonInterface when you need Carbon's utility API
  • Use DateTimeInterface for simpler cases
php
public function handleViaCarbon(CarbonInterface $when): void {}
public function logCreatedAt(DateTimeInterface $timestamp): void {}

5. Why use CarbonImmutable ​

Problem with Carbon (mutable)How CarbonImmutable helps
$dt->addDay() mutates the original $dtMethods return a new instance
Side effects are hard to debugImmutability makes behavior predictable
setTimezone() can have broad impactNo side effects
php
$expiresAt = Carbon::now();
$expiresAt->addMinutes(5); // mutates $expiresAt

$expiresAt = CarbonImmutable::now();
$expiresAt->addMinutes(5); // $expiresAt unchanged

6. Casting in Eloquent models ​

php
protected function casts(): array
{
    return [
        'created_at' => 'immutable_datetime',
        'updated_at' => 'immutable_datetime',
        'delivery_date' => 'immutable_datetime',
    ];
}

Note

  • Use the immutable_datetime cast (Laravel 10+)
  • Add PHPDoc so IDEs and PHPStan can check types accurately

Internal engineering documentation