Carbon::parse

Builds a Carbon instance from almost any date string, including relative phrases like 'next friday'.

Signature
public static function parse(DateTimeInterface|WeekDay|Month|string|int|float|null $time, DateTimeZone|string|int|null $timezone = null): static

Parameters

ParameterTypeDescription
$$timeDateTimeInterface|WeekDay|Month|string|int|float|nullThe value to interpret. Anything strtotime() understands, another date object, a Unix timestamp as int or float, or null for the current moment.
$$timezoneoptionalDateTimeZone|string|int|null= nullTimezone 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

Try it yourself
Loading editor…
Press Run to execute the code.

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'.

Example · php
<?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:00

Guarding 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.

Example · php
<?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'));        // NULL

Timestamps 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.

Example · php
<?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

  • Be the first to comment on this lesson.