• Модуль: bizproc
  • Путь к файлу: ~/bitrix/modules/bizproc/classes/general/calc.php
  • Класс: CBPCalc
  • Вызов: CBPCalc::functionWorkDateAdd
private function functionWorkDateAdd($args)
{
	if (!is_array($args))
		$args = [$args];

	$ar = $this->ArrgsToArray($args);
	$date = array_shift($ar);
	$offset = $this->getDateTimeOffset($date);
	$paramInterval = array_shift($ar);
	$user = array_shift($ar);

	if ($user)
	{
		$date = $this->FunctionToUserDate([$user, $date]);
		$offset = $this->getDateTimeOffset($date);
	}

	if (($date = $this->makeTimestamp($date, true)) === false)
		return null;

	if (empty($paramInterval) || !CModule::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);
}