briannesbitt/Carbon · error · InvalidIntervalException

Empty interval is not accepted.

Error message

Empty interval is not accepted.

What it means

A period must advance by a non-zero amount. After conversion, setDateInterval() rejects intervals whose specification is exactly 'PT0S' with no fractional seconds (f) and no step, because iterating a zero interval would never move and spin forever (src/Carbon/CarbonPeriod.php:994).

Source

Thrown at src/Carbon/CarbonPeriod.php:994

     *
     * @return static
     */
    public function setDateInterval(mixed $interval, Unit|string|null $unit = null): static
    {
        if ($interval instanceof Unit) {
            $interval = $interval->interval();
        }

        if ($unit instanceof Unit) {
            $unit = $unit->name;
        }

        if (!$interval = CarbonInterval::make($interval, $unit)) {
            throw new InvalidIntervalException('Invalid interval.');
        }

        if ($interval->spec() === 'PT0S' && !$interval->f && !$interval->getStep()) {
            throw new InvalidIntervalException('Empty interval is not accepted.');
        }

        $self = $this->copyIfImmutable();
        $self->dateInterval = $interval;

        $self->isDefaultInterval = false;

        $self->handleChangedParameters();

        return $self;
    }

    /**
     * Reset the date interval to the default value.
     *
     * Difference with simply setting interval to 1-day is that P1D will not appear when calling toIso8601String()
     * and also next adding to the interval won't include the default 1-day.
     */

View on GitHub (pinned to b13f05955d)

Solutions

  1. Guard computed intervals: if the amount is 0, reject the input or default to a sensible unit
  2. Use a real step: 'P1D', 'PT1S', or the integer 1
  3. If sub-second stepping was intended, give the interval a step or microsecond fraction: CarbonInterval::milliseconds(500) or ->stepBy()? use a non-empty spec such as 'PT0.5S'

Example fix

// before
$diff = $start->diffAsCarbonInterval($end); // can be PT0S
$period->setDateInterval($diff); // Empty interval is not accepted

// after
$diff = $start->diffAsCarbonInterval($end);
if ($diff->isEmpty()) {
    throw new InvalidArgumentException('Start and end must differ');
}
$period->setDateInterval($diff);
Defensive patterns

Strategy: validation

Validate before calling

$made = CarbonInterval::make($input);
if ($made === null || ($made->spec() === 'PT0S' && !$made->f && !$made->getStep())) {
    throw new InvalidArgumentException('Interval must be non-zero');
}
$period->setDateInterval($made);

Prevention

When it happens

Trigger: ->setDateInterval(0); ->setDateInterval('PT0S'); ->setDateInterval(CarbonInterval::minutes(0)); a computed interval that happens to be zero, e.g. ->setDateInterval($start->diffAsCarbonInterval($end)) when both dates are identical.

Common situations: Intervals derived from user-chosen date pairs that can be equal; dividing a duration by a count that rounds to 0; placeholder/test intervals of 0.

Related errors


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