Carbon::parse
Builds a Carbon instance from almost any date string, including relative phrases like 'next friday'.
public static function parse(DateTimeInterface|WeekDay|Month|string|int|float|null $time, DateTimeZone|string|int|null $timezone = null): staticParameters
| Parameter | Type | Description |
|---|---|---|
$$time | DateTimeInterface|WeekDay|Month|string|int|float|null | The value to interpret. Anything strtotime() understands, another date object, a Unix timestamp as int or float, or null for the current moment. |
$$timezoneoptional | DateTimeZone|string|int|null= null | Timezone the string should be read in and carried by the result. Ignored when the string itself carries an offset such as +02:00 or Z. |
Return value
staticA Carbon instance representing the parsed value, in the given timezone or the default one.
Errors
Throws Carbon\Exceptions\InvalidFormatException when the string cannot be interpreted, and Carbon\Exceptions\InvalidTimeZoneException for an unknown timezone.
Changelog
- PHP 3.0$time no longer has a default value: Carbon::parse() with no arguments raises an ArgumentCountError, where Carbon 2 returned the current moment. Pass null explicitly, or call Carbon::now().
Carbon::parse() is the fluent form of the constructor: it hands the string to PHP's date parser, so everything strtotime() accepts works — ISO 8601 strings, '2026-03-14 09:30', '+3 days', 'next friday', 'first day of next month'. It is the right tool for values you control: an API payload with a documented format, a config value, a database column read back as a string.
Where it bites
It is the wrong tool for raw user input, for two reasons. Slash-separated dates are read as month-first, so '03/04/2026' silently becomes 3 March, not 4 March — no exception, just a wrong date six months out. And genuinely unparseable text throws InvalidFormatException, which is an exception you must catch rather than a value you can check. When the input format is known, use createFromFormat; when it is user-supplied, validate first with the date_format rule.
Relative strings and the clock
Relative phrases are resolved against the current moment, so they respect Carbon::setTestNow(). Note that 'next friday' resets the time to midnight while '+3 days' keeps the current time of day — a difference that surprises people comparing the two.
Example
When to use it
- Turning an ISO 8601 timestamp from a webhook or API response into a date object.
- Reading a date column that came back as a raw string from a query builder call.
- Resolving a relative expression such as '+30 days' from a configuration value.
Frequently asked questions
Why does Carbon::parse('03/04/2026') give me March instead of April?
Slash-separated dates are read in US month/day/year order by PHP's parser, so 03/04/2026 is 3 March 2026. Use dashes or dots for day-first order, or better, use Carbon::createFromFormat('d/m/Y', ...) so the format is explicit.
How do I check whether a string is a valid date without an exception?
Wrap the call in a try/catch for Carbon\Exceptions\InvalidFormatException and return null on failure, or validate the input first with Laravel's date or date_format rule. There is no parse method that returns false instead of throwing.
Does Carbon::parse respect the timezone argument for ISO strings?
Only when the string does not already carry an offset. '2026-03-14T09:30:00Z' or '...+02:00' pins the instant itself, and the timezone argument is ignored; '2026-03-14 09:30' is read as wall-clock time in the timezone you pass.
More examples
Reading a timestamp from an API response
Both calls produce the same instant: the trailing Z in the payload already pins the offset, so the timezone argument is ignored. It only takes effect for strings that carry no offset of their own, such as '2026-03-14 09:30'.
<?php
use Carbon\Carbon;
use Illuminate\Support\Facades\Http;
$payload = Http::get('https://api.example.com/events/42')->json();
$startsAt = Carbon::parse($payload['starts_at']); // '2026-03-14T09:30:00Z'
$localised = Carbon::parse($payload['starts_at'], 'Europe/Madrid');
echo $startsAt->toIso8601String(), PHP_EOL; // 2026-03-14T09:30:00+00:00
echo $localised->toIso8601String(), PHP_EOL; // 2026-03-14T09:30:00+00:00Guarding untrusted input
Unparseable text raises InvalidFormatException rather than returning false, so a caller that forgets the try/catch turns a typo into a 500. Note that this wrapper still accepts '03/04/2026' and reads it month-first — catching the exception does not make the parse safe, only survivable.
<?php
use Carbon\Carbon;
use Carbon\Exceptions\InvalidFormatException;
function safeParse(string $input): ?Carbon
{
try {
return Carbon::parse($input);
} catch (InvalidFormatException) {
return null;
}
}
var_dump(safeParse('2026-03-14')?->toDateString()); // string(10) "2026-03-14"
var_dump(safeParse('sometime next quarter')); // NULLTimestamps and other date objects
An integer is treated as a Unix timestamp, and any DateTimeInterface instance — including a PHP DateTime or another Carbon — is converted directly. The '@' string form works too, but it always lands in UTC regardless of the timezone argument.
<?php
use Carbon\Carbon;
echo Carbon::parse(1773481267)->toDateTimeString(), "\n"; // 2026-03-14 09:41:07
echo Carbon::parse(new DateTime('2026-03-14 09:41:07'))->toDateTimeString(), "\n";
echo Carbon::parse('@1773481267')->toDateTimeString(), "\n"; // 2026-03-14 09:41:07
Discussion