What it is
Carbon extends PHP's DateTime with a fluent API, human-readable differences, localisation and testing helpers.
Carbon instances are DateTime subclasses, so they work anywhere DateTime does, with fluent modification, comparison and formatting on top.
Installation
composer require nesbot/carbonGetting started
The smallest useful thing you can do with it, and what each part means.
php
<?php
use Carbon\Carbon;
$now = Carbon::now('UTC');
$due = $now->copy()->addDays(30)->startOfDay();
// copy() matters — Carbon methods mutate in place by default.
$wrong = $now->addDays(30); // $now is now 30 days later too
if ($now->greaterThan($due)) { /* overdue */ }
echo $now->diffForHumans(); // "2 hours ago"
echo $due->isoFormat('dddd, D MMMM YYYY'); // "Friday, 5 September 2026"
echo $now->diffInDays($due); // 30
$parsed = Carbon::parse('2026-08-07T12:00:00Z');Advanced usage
Where the library earns its place over a simpler alternative.
php
<?php
// Deterministic tests for time-dependent logic.
Carbon::setTestNow(Carbon::parse('2026-01-01 09:00:00'));
$subscription = new Subscription();
self::assertSame('2026-02-01', $subscription->nextBillingDate()->toDateString());
Carbon::setTestNow(); // always reset, or later tests inherit the frozen time
// Time zone handling
$utc = Carbon::parse('2026-08-07 12:00', 'UTC');
$local = $utc->copy()->setTimezone('Europe/London'); // 13:00 BST
// Business-day arithmetic
$deadline = Carbon::now()->addWeekdays(5);Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- A date changed unexpectedly elsewhere
- Carbon mutates in place. Use copy() before modifying, or switch to CarbonImmutable.
- Tests fail depending on the time of day
- Real time leaked into an assertion. Freeze it with setTestNow.
Best practices
- Prefer CarbonImmutable; the mutable API causes surprising action at a distance.
- Always reset setTestNow() in tearDown or the frozen time leaks into other tests.
- Store timestamps in UTC and convert only for display.
- Use diffForHumans for display only — never parse it back.
Background
Why it exists, and what it was reacting to.
PHP's built-in DateTime is capable but awkward. Carbon wraps it with readable methods and, crucially, a way to freeze time in tests — which is why it ships with Laravel.
