Carbon (nesbot/carbon): a PHP DateTime extension for readable date code
A simple PHP API extension for DateTime.
At a glance
- What is it?
- Carbon wraps PHP's DateTime in a fluent API with relative-time helpers and hundreds of locales. It is aimed at PHP developers who write date arithmetic often enough that the native classes become painful.
- Who is it for?
- Adopt Carbon if your PHP codebase already does date arithmetic in application or view layers and you want diffForHumans, locale-aware formatting and a mockable now without writing it yourself. Skip it if you only need to parse or format a couple of timestamps, where plain DateTime is enough, or if you refuse a dependency in a hot path you have not profiled.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem Carbon solves, and who it is for
PHP's DateTime and DateTimeImmutable are correct but verbose. Adding a day means constructing an interval, and formatting a human-readable relative time means writing your own pluralisation and translation tables. Carbon is a wrapper around those classes that keeps the same semantics while exposing a fluent, chainable surface. The README describes it as "An international PHP extension for DateTime", and the examples lean heavily on that: Carbon::now()->addDay(), Carbon::now()->subWeek(), Carbon::createFromDate(1975, 5, 21)->age. The audience is PHP application developers who already reach for DateTime and want shorter code for common operations. It is not a calendar library, a scheduler or a timezone database. It sits on top of the platform's date handling and inherits its constraints, including the 2038 problem the README jokes about with Carbon::create(2038, 01, 19, 3, 14, 7, 'GMT').
How Carbon extends DateTime under the hood
Carbon subclasses the native date classes and adds methods rather than replacing the underlying representation. The README's example output shows the practical consequence: printf("Right now is %s", Carbon::now()->toDateTimeString()) works because the object implements __toString(), so an instance can be dropped into a string context without an explicit format call. Locale handling is the second layer. The README states that over 200 languages and over 500 regional variants are supported, and demonstrates it with Carbon::now()->subMinutes(2)->diffForHumans() returning '2 minutes ago' and the same call after ->locale('zh_CN') returning '2分钟前'. Formatting goes through isoFormat, which takes tokens such as LLLL to produce 'Tuesday, July 23, 2019 2:51 PM', or 'mardi 23 juillet 2019 14:51' under fr_FR. The third layer is testability. Carbon::setTestNow() freezes the clock for the process and Carbon::setTestNow() with no argument restores normal behaviour, which is how the README's 2038 example avoids actually waiting. One detail worth reading twice: the README says comparisons are always done in UTC. That is a design decision, not an accident, and it is the part of the API most likely to surprise someone who assumes local wall-clock comparison.
Installing Carbon with Composer and running a first snippet
Composer is the documented path. The README gives the command directly:
composer require nesbot/carbonAfter that, the package is available through the Composer autoloader, and the README shows the require line and a first call. The expected output is the current timestamp rendered by Carbon's __toString().
<?php
require 'vendor/autoload.php';
use Carbon\Carbon;
printf("Now: %s", Carbon::now());The README also documents a no-Composer route: download the latest release from the GitHub releases page, put the contents of the ZIP archive into a directory in your project, and require autoload.php from that directory. The README's own framing of that option is blunt ("Why are you not using composer?"), so treat it as a fallback rather than a recommended setup. For a first real use, the diffForHumans example is the shortest path to seeing what Carbon adds over DateTime:
<?php
use Carbon\Carbon;
echo Carbon::now()->subMinutes(2)->diffForHumans(); // '2 minutes ago'
echo Carbon::now()->subMinutes(2)->locale('zh_CN')->diffForHumans(); // '2分钟前'If you see the English string and then the Chinese one, locale switching is wired correctly. If both come out English, the locale data is not being picked up in your environment, and that is the first thing to check before filing anything.
Carbon's UTC comparison rule and other sharp edges
The README states plainly that comparisons are always done in UTC. Code that constructs two Carbon instances in different zones and compares them will not compare the wall-clock strings a user sees. It will compare instants. That is usually what you want, but it is not what every developer assumes when they read a line like Carbon::now()->gte($internetWillBlowUpOn). The diffInDays behaviour has a similar trap. The README notes that without a parameter the difference is calculated from now, while $a->diff($b) counts from $a to $b, and the sample output shows that this can produce negative values: -5037.4560 for a future date. A negative "days until" is easy to misread as a bug in your own code. Floating-point day counts (19817.6771) are another thing to handle deliberately; if you need whole days, round explicitly. The test clock is a sharp edge too. setTestNow() is global to the process, so a test that sets it and does not reset it can leak a frozen clock into later tests. The README's own example resets with a bare Carbon::setTestNow() call, and that reset is not optional in a test suite. Finally, the repository is migrating from briannesbitt/Carbon to CarbonPHP/carbon. The README says code on both will be kept up to date and that the only impact is having to search two places for issues and pull requests. That is a mild inconvenience, not a functional risk, but it does mean links and documentation may point at either location.
When plain DateTime is the better choice
Carbon earns its place when date logic is spread across controllers, models, views and tests. If your codebase touches dates in one or two places, the dependency buys you very little. A single DateTimeImmutable formatted with a fixed pattern needs no wrapper, and the native class has no extra autoload cost. Carbon also is not the right tool when the requirement is calendar semantics rather than instant arithmetic: recurring events, business-day calculations and holiday rules are not what the README demonstrates, and the documentation it points to is the place to check before assuming those are covered. The 2038 example in the README is a reminder that Carbon inherits the platform's integer timestamp limits rather than abstracting them away. If your application must handle dates beyond that boundary, the question is about your PHP build and platform, not about Carbon.
Carbon versus the raw DateTimeImmutable workflow
The honest alternative is to stay with DateTimeImmutable and write the small helpers you actually need. The difference in approach is where the code lives. Carbon puts the helpers on the object: addDay, subWeek, diffForHumans, isoFormat, locale, setTestNow. The native workflow puts them in your own utility class or in explicit DateInterval construction at each call site. The native path has no third-party dependency and no locale data to ship, and it is immune to any behaviour change in a wrapper. Carbon's path gives you consistent relative-time strings across more than 200 languages, which is genuinely tedious to reproduce by hand, and a documented way to freeze time in tests. The trade-off is that Carbon's convenience methods encode opinions, and the UTC comparison rule is one of them. If your team already has a date utility layer that handles locale and testing, adding Carbon on top means two places where date behaviour is defined.
Maintenance, licence and upgrade cost
The repository is not archived, and the last push was on 2026-09-15, days before this writing, with releases 3.14.0 and 3.13.3 both dated 2026-09-12 and 3.13.2 on 2026-08-08. That is a project that ships often, which cuts both ways: fixes arrive quickly, and so do minor releases you may need to track. The README's Composer example pins the major line with "nesbot/carbon": "^3", which is the sane default for most applications because it accepts patch and minor updates within version 3. The migration note about moving from briannesbitt/Carbon to CarbonPHP/carbon is the main administrative cost to plan for; the README states the code is kept up to date on both, so the practical work is updating links and knowing where to search. Carbon is MIT licensed, which is permissive and imposes no copyleft obligation on your application. That is a statement about the licence text, not legal advice; if your organisation has a policy review for dependencies, run it through that. Security reports go through the Tidelift security contact listed in the README, not through public issues, which is worth noting in your own incident process.
Editorial conclusion
Adopt Carbon if your PHP codebase already does date arithmetic in application or view layers and you want diffForHumans, locale-aware formatting and a mockable now without writing it yourself. Skip it if you only need to parse or format a couple of timestamps, where plain DateTime is enough, or if you refuse a dependency in a hot path you have not profiled. Before adopting, verify which repository you are installing from (briannesbitt/Carbon or CarbonPHP/carbon), confirm the package name resolves to nesbot/carbon, and read the documentation section on UTC comparison before you rely on gte or diffInDays in timezone-sensitive logic.
Frequently asked questions
What is Carbon (nesbot/carbon) in simple terms?
It is a PHP API extension for DateTime, described in the README as an international extension for the native date classes. It adds fluent methods such as addDay and subWeek, relative-time output through diffForHumans, and locale-aware formatting.
How do I install Carbon in a PHP project?
The README documents Composer as the primary route with composer require nesbot/carbon, after which you require vendor/autoload.php. It also describes a no-Composer option: download the latest release ZIP, place its contents in a project directory, and require that directory's autoload.php.
How do I use Carbon to show a time like "2 minutes ago"?
Call diffForHumans on a Carbon instance, as in Carbon::now()->subMinutes(2)->diffForHumans(), which the README shows returning '2 minutes ago'. Chaining ->locale('zh_CN') before the call returns the localised string '2分钟前'.
How can I freeze time in tests with Carbon?
The README uses Carbon::setTestNow() with a Carbon instance to mock the current time, and a bare Carbon::setTestNow() call to return to normal behaviour. Because it affects the process clock, resetting it after the test matters.
Which repository should I use for Carbon, briannesbitt/Carbon or CarbonPHP/carbon?
The README states the repository is being migrated from briannesbitt/Carbon to CarbonPHP/carbon, that code on both will be kept up to date, and that the only impact is having to search both places for issues and pull requests.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/briannesbitt-carbon)