briannesbitt/Carbon · error · NotACarbonClassException

$dateClass

Error message

$dateClass

What it means

setDateClass() changes the class of dates the period yields (Carbon vs CarbonImmutable or your subclass). The target must be a class-string implementing CarbonInterface, verified with is_a($dateClass, CarbonInterface::class, true); native DateTime/DateTimeImmutable, non-Carbon classes and typos throw NotACarbonClassException with the given name (src/Carbon/CarbonPeriod.php:944).

Source

Thrown at src/Carbon/CarbonPeriod.php:944

     *
     * @return static
     */
    public function clone()
    {
        return clone $this;
    }

    /**
     * Set the iteration item class.
     *
     * @param string $dateClass
     *
     * @return static
     */
    public function setDateClass(string $dateClass)
    {
        if (!is_a($dateClass, CarbonInterface::class, true)) {
            throw new NotACarbonClassException($dateClass);
        }

        $self = $this->copyIfImmutable();
        $self->dateClass = $dateClass;

        if (is_a($dateClass, Carbon::class, true)) {
            $self->options = $self->options & ~static::IMMUTABLE;
        } elseif (is_a($dateClass, CarbonImmutable::class, true)) {
            $self->options = $self->options | static::IMMUTABLE;
        }

        return $self;
    }

    /**
     * Returns iteration item date class.
     *
     * @return string

View on GitHub (pinned to b13f05955d)

Solutions

  1. Pass Carbon::class or CarbonImmutable::class (or a subclass of either)
  2. Make custom classes extend Carbon/CarbonImmutable or implement CarbonInterface
  3. If you want native objects as output, use $period->cast(DateTimeImmutable::class) or ->toDatePeriod() instead of setDateClass()

Example fix

// before
$period->setDateClass(\DateTimeImmutable::class); // NotACarbonClassException

// after
$period->setDateClass(\Carbon\CarbonImmutable::class);
// or, for native objects at iteration time
foreach ($period->cast(\DatePeriod::class) as $date) { /* $date is DateTimeInterface */ }
Defensive patterns

Strategy: type-guard

Type guard

/** @param class-string $dateClass */
function isCarbonDateClass(string $dateClass): bool
{
    return is_a($dateClass, \Carbon\CarbonInterface::class, true);
}

$period->setDateClass(isCarbonDateClass($class) ? $class : \Carbon\CarbonImmutable::class);

Prevention

When it happens

Trigger: $period->setDateClass(DateTimeImmutable::class); ->setDateClass('App\\Value\\MyDate') where MyDate neither extends Carbon/CarbonImmutable nor implements CarbonInterface; passing an object instance instead of a class-string.

Common situations: Trying to make a period yield native PHP date objects; introducing custom date value objects that wrap instead of extend Carbon; IDE autocomplete inserting the wrong class name.

Related errors


AI-assisted analysis of briannesbitt/Carbon@b13f05955d (2026-08-17). Data as JSON: /api/errors/96268828b2d7914a. Report an issue: GitHub.