@param \DateInterval $interval

@return $this|\DateTime|Time

@throws \RuntimeException
Frozen.
@throws \Exception
Propagated.
11686
public function add(/*\DateInterval*/ $interval) : \DateTime /*self invariant*/
    {
        // NB: Argument type hinting (\DateInterval $interval)
        // would provoke E_WARNING when cloning.
        // Catch 22: Specs say that native \DateTime method is type hinted,
        // but warning when cloning says it isn't.

        if ($this->frozen) {
            throw new \RuntimeException(get_class($this) . ' is read-only, frozen.');
        }
        return parent::add($interval);
    }
27747
public function formatInterval(\DateInterval $dateInterval): string
    {
        $format = 'P';

        if (0 < $dateInterval->y) {
            $format .= $dateInterval->y.'Y';
        }

        if (0 < $dateInterval->m) {
            $format .= $dateInterval->m.'M';
        }

        if (0 < $dateInterval->d) {
            $format .= $dateInterval->d.'D';
        }

        if (0 < $dateInterval->h || 0 < $dateInterval->i || 0 < $dateInterval->s) {
            $format .= 'T';
        }

        if (0 < $dateInterval->h) {
            $format .= $dateInterval->h.'H';
        }

        if (0 < $dateInterval->i) {
            $format .= $dateInterval->i.'M';
        }

        if (0 < $dateInterval->s) {
            $format .= $dateInterval->s.'S';
        }

        return $format;
    }
170568
final public static function formatInterval($interval, $parts = 0)
    {
        $interval = self::recalculateInterval($interval);

        $format = [];
        if ($interval->y !== 0) {
            $format[] = Yii::t(
                'datetime',
                '{y,plural,one{# year} few{# years} many{# years} other{# years}}',
                ['y' => $interval->y]
            );
        }

        if ($interval->m !== 0) {
            $format[] = Yii::t(
                'datetime',
                '{m,plural,one{# month} few{# months} many{# months} other{# months}}',
                ['m' => $interval->m]
            );
        }

        if ($interval->d !== 0) {
            $format[] = Yii::t(
                'datetime',
                '{d,plural,one{# day} few{# days} many{# days} other{# days}}',
                ['d' => $interval->d]
            );
        }

        if ($interval->h !== 0) {
            $format[] = Yii::t(
                'datetime',
                '{h,plural,one{# hour} few{# hours} many{# hours} other{# hours}}',
                ['h' => $interval->h]
            );
        }

        if ($interval->i !== 0) {
            $format[] = Yii::t(
                'datetime',
                '{i,plural,one{#minute} few{# minutes} many{# minutes} other{# minutes}}',
                ['i' => $interval->i]
            );
        }

        if ($interval->s !== 0) {
            $format[] = Yii::t(
                'datetime',
                '{s,plural,one{# second} few{# seconds} many{# seconds} other{# seconds}}',
                ['s' => $interval->s]
            );
        }

        if (count($format) === 0) {
            return "";
        }

        if (($parts > 0) && (count($format) > 1)) {
            $values = [];
            while ((count($values) < $parts) && (count($format) > 0)) {
                $values[] = array_shift($format);
            }
        } else {
            $values = $format;
        }

        return implode(" ", $values);
    }
1265690
private function evaluateOpeningIntervals(\DateTime $context)
    {
        $contextHash = $context->format(\DateTime::ISO8601);

        if (!isset($this->openingIntervalsCache[$contextHash])) {
            $intervals = call_user_func($this->openingIntervalsEvaluator, $context);

            if (!is_array($intervals)) {
                throw new \RuntimeException('The special day evaluator must return an array of opening intervals.');
            }

            $this->openingIntervalsCache[$contextHash] = $intervals;
        }

        $this->setOpeningIntervals($this->openingIntervalsCache[$contextHash]);
    }
429845
private static function dateIntervalToString(\DateInterval $interval)
    {

        // Reading all non-zero date parts.
        $date = array_filter([
            'Y' => $interval->y,
            'M' => $interval->m,
            'D' => $interval->d,
        ]);

        // Reading all non-zero time parts.
        $time = array_filter([
            'H' => $interval->h,
            'M' => $interval->i,
            'S' => $interval->s,
        ]);

        $specString = 'P';

        // Adding each part to the spec-string.
        foreach ($date as $key => $value) {
            $specString .= $value.$key;
        }
        if (count($time) > 0) {
            $specString .= 'T';
            foreach ($time as $key => $value) {
                $specString .= $value.$key;
            }
        }

        return $specString;
    }
578204
protected function resolveTimeFormat(\DateInterval $interval): string
    {
        $format = '';

        if ($interval->h > 0) {
            $format .= '%hH';
        }

        if ($interval->i > 0) {
            $format .= '%iM';
        }

        if ($interval->s > 0) {
            $format .= '%sS';
        }

        return $format;
    }
62485
private function getIntervalUnits(\DateTime $date1, \DateTime $date2, string $intervalFormat)
    {
        $result = 0;
        try {
            $interval = new \DateInterval($intervalFormat);
            $periods  = new \DatePeriod($date1, $interval, $date2);

            $result = max(0, iterator_count($periods) - 1);
        } catch (\Exception $e) {
        }

        return $result;
    }
515165
public function add(DateInterval $interval)
	{
		$years   = $this->y + $interval->y;
		$months  = $this->m + $interval->m;
		$days    = $this->d + $interval->d;
		$hours   = $this->h + $interval->h;
		$minutes = $this->i + $interval->i;
		$seconds = $this->s + $interval->s;

		$spec = sprintf('P%sY%sM%sDT%sH%sM%sS', $years, $months, $days, $hours, $minutes, $seconds);

		return new DateInterval($spec);
	}
1101729
public static function toSecondsUsingDays(\DateInterval $interval)
    {
        $seconds = (string) $interval->s;

        if ($interval->i) {
            $seconds = bcadd($seconds, bcmul($interval->i, self::SECONDS_MINUTE));
        }

        if ($interval->h) {
            $seconds = bcadd($seconds, bcmul($interval->h, self::SECONDS_HOUR));
        }

        if ((false !== $interval->days) && (0 <= $interval->days)) {
            $seconds = bcadd($seconds, bcmul($interval->days, self::SECONDS_DAY));
        } else {
            throw new InvalidArgumentException(
                'The "days" property is not set.'
            );
        }

        return $seconds;
    }
948916
public function invert()
	{
		$interval = $this->copy($this->interval);
		$interval->invert = $interval->invert ? 0 : 1;

		return new DateInterval($interval);
	}
384591
public function add($interval)
    {
        if (self::$_immutable) {
            self::$_immutable = false;
            $newDate = clone $this;
            $newDate->add($interval);
            self::$_immutable = true;

            return $newDate;
        } else {
            return parent::add($interval);
        }
    }
673081
protected function _getInterval($interval) {
		if ($interval !== null) {
			return $interval;
		} elseif (!empty($this->params['interval'])) {
			return $this->params['interval'];
		} else {
			return '1 day';
		}
	}
1229153
public function setExpiresIn(DateInterval $interval)
    {
        $now = new DateTimeImmutable();
        $expire = $now->add($interval);
        $this->setExpiresInSeconds($expire->getTimestamp() - $now->getTimestamp());
        return $this;
    }
562301
public function addInterval($number, $period)
  {
    $int = new \DateInterval(sprintf('P%d%s', abs($number), $period));

    if ($number > 0) {
      $this->add($int);
    } elseif ( $number < 0) {
      $this->sub($int);
    }

    return $this;
  }
212594
public static function modify($dateAsString, $interval, $format = self::DEFAULT_TIME_FORMAT)
    {
        $dateTime = new DateTime($dateAsString);
        return $dateTime->modify($interval)->format($format);
    }
955398
public function add($interval = null)
	{
		if ( ! $interval instanceOf DateInterval)
		{
			if (is_numeric($interval))
			{
				$delta = intval($interval);
				$interval = new DateInterval('PT'.strval(abs($delta)).'S');
				if ($delta < 0)
				{
					$interval->invert = 1;
				}
			}
		}

		if ($this->datetime->add($interval))
		{
			return $this;
		}

		return false;
	}
494882
public static function normalize($interval)
    {
        $from = new \DateTime("1970-01-01 00:00:00");
        $to = clone $from;
        $to = $to->add($interval);
        $result = $from->diff($to);

        return ($result !== false) ? $result : $interval;
    }