briannesbitt/Carbon · error · InvalidArgumentException

Interval objects cannot be multiplied by a non-integer value

Error message

Interval objects cannot be multiplied by a non-integer value.

What it means

When the first argument of add()/sub() is an interval-like value (CarbonInterval, DateInterval converted to closure, CarbonConverterInterface or a Closure), Carbon applies it N times in a loop where the count must be a whole number. disallowDecimalPart() compares the float value against its int cast and throws InvalidArgumentException for any fractional multiplier such as 1.5 or 0.5 - you cannot apply an interval one and a half times.

Source

Thrown at src/Carbon/Traits/Units.php:609

    }

    /**
     * Set current day of the instance to the passed value if it exits in the
     * current month, else set current day to the last day of the month.
     */
    public function setAnchorDay(int $anchorDay): static
    {
        if ($anchorDay < 1) {
            throw new InvalidArgumentException('$anchorDay must be greater than 0');
        }

        return $this->day(min($anchorDay, $this->daysInMonth));
    }

    private static function disallowDecimalPart(mixed $value): void
    {
        if (((float) $value) !== ((float) (int) $value)) {
            throw new InvalidArgumentException(
                'Interval objects cannot be multiplied by a non-integer value.',
            );
        }
    }

    private function getOverflowMode(
        OverflowMode|bool|null $overflow = null,
        ?int $anchorDay = null,
    ): ?OverflowMode {
        if ($anchorDay !== null) {
            $overflow ??= OverflowMode::AnchorDay;

            if ($overflow !== OverflowMode::AnchorDay) {
                throw new InvalidArgumentException(
                    '$anchorDay can be set only $overflow = OverflowMode::AnchorDay',
                );
            }
        }

View on GitHub (pinned to b13f05955d)

Solutions

  1. Convert the fraction into smaller units before adding: instead of add(CarbonInterval::days(2), 1.5) use ->addUnit('hour', 72) or CarbonInterval::hours(72)
  2. Round/cast the multiplier deliberately: (int) floor($times) or ceil() per business rule, and handle the remainder explicitly
  3. If you need fractional interval scaling, use CarbonInterval's own float-capable multiplication (e.g. CarbonInterval::fromString('2 days')->times(1.5)) and add the resulting interval once
  4. Validate fmod($times, 1) === 0.0 at the boundary when the count comes from division

Example fix

// before
$date->add(CarbonInterval::days(2), 1.5); // throws

// after
$date->add(CarbonInterval::hours(72)); // 1.5 x 2 days expressed exactly
Defensive patterns

Strategy: validation

Validate before calling

$times = (float) $count;
if (fmod($times, 1.0) !== 0.0) {
    throw new InvalidArgumentException("Interval repeat count must be an integer, got $count");
}
$date->add($interval, (int) $times);

Type guard

function isIntegerMultiplier(int|float|string $value): bool
{
    return is_int($value) || (is_float($value) && fmod($value, 1.0) === 0.0)
        || (is_string($value) && preg_match('/^-?\d+$/', $value) === 1);
}

Try / catch

try {
    $date->add($interval, $times);
} catch (\InvalidArgumentException $e) {
    // fractional count: split into whole repeats + remainder in smaller units
    $date->add($interval, (int) floor($times));
    $date->addUnit('hour', $interval->totalHours * fmod($times, 1.0));
}

Prevention

When it happens

Trigger: $date->add(CarbonInterval::days(2), 1.5); $date->add($someIntervalConverter, 0.5); a computed multiplier like $total / $chunkSize that lands on 2.25; passing '1.5' as a numeric string multiplier; passing -1.5 to invert and scale an interval in sub().

Common situations: Generic 'repeat interval X times' helpers receiving user quotas that are not multiples of the chunk; batch/split logic computing counts by division; migrating code that multiplied CarbonInterval::times(...) (which supports floats on some units) into the add(..., $times) signature which does not.

Related errors


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