Skip to content

Carbon

Developer UtilitiesDate & TimePHP

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/carbon

Getting started

The smallest useful thing you can do with it, and what each part means.

Fluent dates and differences
<?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');
Mutability is Carbon's sharpest edge. Use copy(), or CarbonImmutable, which behaves identically but returns new instances — most teams now default to the immutable variant.

Advanced usage

Where the library earns its place over a simpler alternative.

Freezing time in tests
<?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);
setTestNow is the reason Carbon is worth the dependency: testing anything involving 'now' is otherwise either flaky or requires injecting a clock everywhere.

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.