• Модуль: crm
  • Путь к файлу: ~/bitrix/modules/crm/lib/settings/worktime.php
  • Класс: Bitrix\Crm\Settings\WorkTime
  • Вызов: WorkTime::detectNearestWorkDateTime
public function detectNearestWorkDateTime(int $days = 0, int $hours = 0, DateTime $baseDateInServerTimezone = null): DateTime
{
	$days = $days < 0 ? 0 : $days;
	if ($days > self::NUM_OF_ATTEMPTS_DETECT_NEAREST_DATE)
	{
		throw new ArgumentException('Must be less than ' . (self::NUM_OF_ATTEMPTS_DETECT_NEAREST_DATE +1), 'days');
	}

	$hours = $hours < 0 ? 0 : $hours;
	if ($hours > 22)
	{
		throw new ArgumentException('Must be less than 23 ', 'hours');
	}

	$interval = sprintf('%d hour', $hours);
	$date = $baseDateInServerTimezone ?? new DateTime(); // use current day if base date not set
	$date = (clone $date)->toUserTime();                 // use user time zone
	$date->add($interval);
	$date->setTime($date->format('H'),0);

	$attemptCount = 0;
	$workDayCount = 0;
	if ($days > 0)
	{
		while ($attemptCount < self::NUM_OF_ATTEMPTS_DETECT_NEAREST_DATE && $workDayCount < $days)
		{
			$attemptCount++;
			$date->add('1 day');
			if ($this->isWorkDay($date))
			{
				$workDayCount++;
			}
		}
	}

	// return default datetime if unable to detect the nearest work date
	if ($attemptCount === self::NUM_OF_ATTEMPTS_DETECT_NEAREST_DATE)
	{
		$currentDate = new DateTime();
		$currentDate = (clone $currentDate)->toUserTime(); // use user time zone
		$currentDate->add('1 hour');
		$currentDate->setTime($currentDate->format('H'),0);

		return CCrmDateTimeHelper::getServerTime($currentDate);
	}

	if (!$this->isWorkTime($date))
	{
		$date->setTime(
			$attemptCount > 0 ? $this->data['TIME_FROM']->hours : $this->data['TIME_TO']->hours,
			0
		);
	}

	return CCrmDateTimeHelper::getServerTime($date);
}