• Модуль: bizproc
  • Путь к файлу: ~/bitrix/modules/bizproc/lib/Calc/Libs/DateLib.php
  • Класс: BitrixBizprocCalcLibsDateLib
  • Вызов: DateLib::callWorkDateAdd
public function callWorkDateAdd(Arguments $args)
{
	$date = $args->getFirstSingle();
	$offset = $this->getDateTimeOffset($date);
	$paramInterval = $args->getSecondSingle();
	$user = $args->getThird();

	if ($user)
	{
		$userArgs = clone $args;
		$userArgs->setArgs([$user, $date]);

		$date = $this->callToUserDate($userArgs);
		$offset = $this->getDateTimeOffset($date);
	}

	$date = $this->makeTimestamp($date, true);

	if ($date === false || ($paramInterval && !is_scalar($paramInterval)))
	{
		return null;
	}

	if (empty($paramInterval) || !MainLoader::includeModule('calendar'))
	{
		return $date;
	}

	$paramInterval = trim($paramInterval);
	$multiplier = 1;
	if (mb_substr($paramInterval, 0, 1) === "-")
	{
		$paramInterval = mb_substr($paramInterval, 1);
		$multiplier = -1;
	}

	$workDayInterval = $this->getWorkDayInterval();
	$intervalMap = [
		"d" => $workDayInterval,
		"day" => $workDayInterval,
		"days" => $workDayInterval,
		"h" => 3600,
		"hour" => 3600,
		"hours" => 3600,
		"i" => 60,
		"min" => 60,
		"minute" => 60,
		"minutes" => 60,
	];

	$interval = 0;
	while (preg_match('/s*([d]+)s*([a-z]+)s*/i', $paramInterval, $match))
	{
		$match2 = mb_strtolower($match[2]);
		if (array_key_exists($match2, $intervalMap))
		{
			$interval += intval($match[1]) * $intervalMap[$match2];
		}

		$p = mb_strpos($paramInterval, $match[0]);
		$paramInterval = mb_substr($paramInterval, $p + mb_strlen($match[0]));
	}

	if (date('H:i:s', $date) === '00:00:00')
	{
		//add start work day seconds
		$date += $this->getCalendarWorkTime()[0];
	}

	$date = $this->getNearestWorkTime($date, $multiplier);
	if ($interval)
	{
		$days = (int)floor($interval / $workDayInterval);
		$hours = $interval % $workDayInterval;

		$remainTimestamp = $this->getWorkDayRemainTimestamp($date, $multiplier);

		if ($days)
		{
			$date = $this->addWorkDay($date, $days * $multiplier);
		}

		if ($hours > $remainTimestamp)
		{
			$date += $multiplier < 0 ? -$remainTimestamp - 60 : $remainTimestamp + 60;
			$date = $this->getNearestWorkTime($date, $multiplier) + (($hours - $remainTimestamp) * $multiplier);
		}
		else
		{
			$date += $multiplier * $hours;
		}
	}

	$date -= $offset;

	return new BizprocBaseTypeValueDateTime($date, $offset);
}