• Модуль: main
  • Путь к файлу: ~/bitrix/modules/main/lib/text/dateconverter.php
  • Класс: BitrixMainTextDateConverter
  • Вызов: DateConverter::createDateUsingMetrics
static function createDateUsingMetrics($type, $metric, &$metricModificator = array(), BitrixMainTypeDateTime $date = null)
{
	$defaultDate = $date? $date: new BitrixMainTypeDateTime();
	$metricModificator = is_array($metricModificator)? $metricModificator: array();

	$workTimeStart = explode('.', BitrixMainConfigOption::get('calendar', 'work_time_start', '9'));
	$timeOfStartDate = str_pad(intval($workTimeStart[0]), 2, "0", STR_PAD_LEFT).':'.str_pad(intval($workTimeStart[1] ?? 0), 2, "0", STR_PAD_LEFT);

	$workTimeEnd = explode('.', BitrixMainConfigOption::get('calendar', 'work_time_end', '18'));
	$timeOfEndDate = str_pad(intval($workTimeEnd[0]), 2, "0", STR_PAD_LEFT).':'.str_pad(intval($workTimeEnd[1] ?? 0), 2, "0", STR_PAD_LEFT);

	$result = null;
	switch($type)
	{
		case 1:
			$metricDate = $defaultDate;
			switch($metric['TYPE'])
			{
				case 'DAYAFTERTOMORROW':
					$metricDate->add('TOMORROW')->add('TOMORROW');
				break;
				case 'TOMORROW':
					$metricDate->add('TOMORROW');
				break;
				case 'YESTERDAY':
					$metricDate->add('YESTERDAY');
				break;
				case 'DAYBEFOREYESTERDAY':
					$metricDate->add('YESTERDAY')->add('YESTERDAY');
				break;
			}

			$modificator = '';
			$metricTime = $timeOfEndDate;

			$metricModificator = self::checkModifierPosition($metric, $metricModificator);

			foreach ($metricModificator as $currentModificator)
			{
				if ($metric['TYPE'] == 'WEEK')
				{
					if (in_array($currentModificator['TYPE'], Array('BEFORE', 'PREVIOUS')))
					{
						$metricDate->add('-1 WEEK');
					}
					else if (in_array($currentModificator['TYPE'], Array('AFTER', 'NEXT')))
					{
						$metricDate->add('1 WEEK');
					}
					else if ($currentModificator['TYPE'] == 'MIDDLEOF')
					{
						$metricDate = self::getDateOfDayOfCurrentWeek('WEDNESDAY', $metricDate);
						$modificator = true;
					}
					else if ($currentModificator['TYPE'] == 'STARTOF')
					{
						$metricDate = self::getDateOfDayOfCurrentWeek('MONDAY', $metricDate);
						$modificator = true;
					}
					else if ($currentModificator['TYPE'] == 'ENDOF')
					{
						$metricDate = self::getDateOfDayOfCurrentWeek('FRIDAY', $metricDate);
						$modificator = true;
					}
				}
				else if ($metric['TYPE'] == 'WEEKEND')
				{
					if (in_array($currentModificator['TYPE'], Array('BEFORE')))
					{
						$metricDate = self::getDateOfDayOfCurrentWeek('SATURDAY', $metricDate);
						$metricDate->add('-1 DAY');
						$modificator = true;
					}
					else if (in_array($currentModificator['TYPE'], Array('PREVIOUS')))
					{
						$metricDate->add('-1 WEEK');
						$metricDate = self::getDateOfDayOfCurrentWeek('SATURDAY', $metricDate);
						$modificator = true;
					}
					else if (in_array($currentModificator['TYPE'], Array('NEXT')))
					{
						$metricDate->add('1 WEEK');
						$metricDate = self::getDateOfDayOfCurrentWeek('SATURDAY', $metricDate);
						$modificator = true;
					}
					else if (in_array($currentModificator['TYPE'], Array('AFTER')))
					{
						$metricDate = self::getDateOfDayOfCurrentWeek('SUNDAY', $metricDate);
						$metricDate->add('1 DAY');
						$modificator = true;
					}
					else if ($currentModificator['TYPE'] == 'MIDDLEOF')
					{
						$metricDate = self::getDateOfDayOfCurrentWeek('SATURDAY', $metricDate);
						$modificator = true;
					}
					else if ($currentModificator['TYPE'] == 'STARTOF')
					{
						$metricDate = self::getDateOfDayOfCurrentWeek('SATURDAY', $metricDate);
						$metricTime = $timeOfStartDate;
						$modificator = true;
					}
					else if ($currentModificator['TYPE'] == 'ENDOF')
					{
						$metricDate = self::getDateOfDayOfCurrentWeek('SUNDAY', $metricDate);
						$modificator = true;
					}
				}
				else if ($metric['TYPE'] == 'MONTH')
				{
					if (in_array($currentModificator['TYPE'], Array('BEFORE', 'PREVIOUS')))
					{
						$metricDate->add('-1 MONTH');
						$numberOfMonth = $metricDate->format('t');
						$metricDate = new BitrixMainTypeDateTime($metricDate->format('Y-m').'-'.$numberOfMonth.' '.$timeOfEndDate.':00', 'Y-m-d H:i:s');
						$modificator = true;
					}
					else if (in_array($currentModificator['TYPE'], Array('AFTER', 'NEXT')))
					{
						$metricDate->add('1 MONTH');
						$numberOfMonth = $metricDate->format('t');
						$metricDate = new BitrixMainTypeDateTime($metricDate->format('Y-m').'-'.$numberOfMonth.' '.$timeOfEndDate.':00', 'Y-m-d H:i:s');
						$modificator = true;
					}
					else if ($currentModificator['TYPE'] == 'MIDDLEOF')
					{
						$numberOfHalfMonth = ceil($metricDate->format('t')/2);
						$metricDate = new BitrixMainTypeDateTime($metricDate->format('Y-m').'-'.$numberOfHalfMonth.' '.$timeOfEndDate.':00', 'Y-m-d H:i:s');
						$modificator = true;
					}
					else if ($currentModificator['TYPE'] == 'STARTOF')
					{
						$metricDate = new BitrixMainTypeDateTime($metricDate->format('Y-m').'-01 '.$timeOfStartDate.':00', 'Y-m-d H:i:s');
						$modificator = true;
					}
					else if ($currentModificator['TYPE'] == 'ENDOF')
					{
						$numberOfMonth = $metricDate->format('t');
						$metricDate = new BitrixMainTypeDateTime($metricDate->format('Y-m').'-'.$numberOfMonth.' '.$timeOfEndDate.':00', 'Y-m-d H:i:s');
						$modificator = true;
					}
				}
				else
				{
					if (in_array($currentModificator['TYPE'], Array('BEFORE', 'PREVIOUS')))
					{
						$metricDate->add('-1 DAY');
					}
					else if (in_array($currentModificator['TYPE'], Array('AFTER', 'NEXT')))
					{
						$metricDate->add('1 DAY');
					}
					else if ($currentModificator['TYPE'] == 'MIDDLEOF')
					{
						$metricTime = '14:00';
					}
					else if ($currentModificator['TYPE'] == 'STARTOF')
					{
						$metricTime = $timeOfStartDate;
					}
					$modificator = true;
				}

				if (in_array($currentModificator['TYPE'], Array('MORNING', 'LUNCH', 'EVENING', 'HHMM')))
				{
					$metricTime = $currentModificator['VALUE'];
					$modificator = true;
				}
			}
			if (!$modificator)
			{
				if ($metric['TYPE'] == 'WEEK')
				{
					if ($metricDate->format('N') == 3)
					{
						$metricDate->add('FRIDAY');
					}
					else if ($metricDate->format('N') < 3)
					{
						$metricDate->add('THURSDAY');
					}
					else if ($metricDate->format('N') != 7)
					{
						$metricDate->add('SUNDAY');
					}
				}
				else if ($metric['TYPE'] == 'WEEKEND')
				{
					if (strtolower($metricDate->format('l')) == 'saturday')
						$metricDate->add('SUNDAY');
					else if (strtolower($metricDate->format('l')) != 'sunday')
						$metricDate->add('SATURDAY');
				}
				else if ($metric['TYPE'] == 'MONTH')
				{
					$numberOfMonth = $metricDate->format('j');
					if ($numberOfMonth > 15)
					{
						$plus = $metricDate->format('t')-$numberOfMonth;
						if ($plus >= 1)
						{
							$metricDate->add($plus.' DAY');
						}
					}
					elseif ($numberOfMonth >= 10)
					{
						$plus = 20-$numberOfMonth;
						$metricDate->add($plus.' DAY');
					}
					else
					{
						$plus = 15-$numberOfMonth;
						$metricDate->add($plus.' DAY');
					}
				}
			}

			$result = new BitrixMainTypeDateTime($metricDate->format('Y-m-d').' '.$metricTime.':00', 'Y-m-d H:i:s');

		break;
		case 2:

			$metricDate = $defaultDate;
			$modificator = '';
			$metricTime = $timeOfEndDate;

			$metricModificator = self::checkModifierPosition($metric, $metricModificator);

			foreach ($metricModificator as $currentModificator)
			{
				$metricDate = self::getDateOfDayOfCurrentWeek($metric['TYPE'], $metricDate);
				if ($currentModificator['TYPE'] == 'BEFORE')
				{
					$metricDate->add('-1 DAY');
				}
				else if ($currentModificator['TYPE'] == 'AFTER')
				{
					$metricDate->add('1 DAY');
				}
				else if ($currentModificator['TYPE'] == 'THIS')
				{
					$metricDate->add('LAST '.$metric['TYPE']);
				}
				else if (in_array($currentModificator['TYPE'], Array('NEXT', 'PREVIOUS')))
				{
					if ($currentModificator['TYPE'] == 'NEXT')
					{
						$metricDate->add('NEXT '.$metric['TYPE']);
					}
					else
					{
						$metricDate->add('PREVIOUS '.$metric['TYPE']);
					}
				}
				else if ($currentModificator['TYPE'] == 'MIDDLEOF')
				{
					$metricTime = '14:00';
				}
				else if ($currentModificator['TYPE'] == 'STARTOF')
				{
					$metricTime = $timeOfStartDate;
				}
				else if (in_array($currentModificator['TYPE'], Array('MORNING', 'LUNCH', 'EVENING', 'HHMM')))
				{
					$metricTime = $currentModificator['VALUE'];
				}
				$modificator = true;
			}
			if (!$modificator)
			{
				$modificator = strtolower($metric['TYPE']) == strtolower($metricDate->format('l'))? 'NEXT ': '';
				$metricDate->add($modificator.$metric['TYPE']);
			}

			$result = new BitrixMainTypeDateTime($metricDate->format('Y-m-d').' '.$metricTime.':00', 'Y-m-d H:i:s');

		break;
		case 3:
			$metricDate = $defaultDate;
			$metricTime = $timeOfEndDate;
			switch($metric['TYPE'])
			{
				case 'BEFORE':
					$metricDate->add('TOMORROW')->add('TOMORROW');
				break;
				case 'AFTER':
					$metricDate->add('TOMORROW');
				break;
				case 'NEXT':
					$metricDate->add('YESTERDAY');
				break;
				case 'PREVIOUS':
					$metricDate->add('YESTERDAY')->add('YESTERDAY');
				break;
				case 'MIDDLEOF':
					$metricTime = '14:00';
				break;
				case 'STARTOF':
					$metricTime = $timeOfStartDate;
				break;
				case 'HHMM':
					$metricTime = $metric['VALUE'];
				break;
			}
			$result = new BitrixMainTypeDateTime($metricDate->format('Y-m-d').' '.$metricTime.':00', 'Y-m-d H:i:s');

		break;
		case 4:
			$modificator = '';
			$metricTime = $timeOfEndDate;

			$metricModificator = self::checkModifierPosition($metric, $metricModificator);

			foreach ($metricModificator as $currentModificator)
			{
				if (in_array($currentModificator['TYPE'], Array('MORNING', 'LUNCH', 'EVENING', 'HHMM')))
				{
					$metricTime = $currentModificator['VALUE'];
				}
			}

			$result = new BitrixMainTypeDateTime($metric['VALUE'].' '.$metricTime.':00', 'Y-m-d H:i:s');

		break;
		case 5:

			$metricDate = $defaultDate;
			$modificator = '';
			$metricTime = $metric['VALUE'];

			$metricModificator = self::checkModifierPosition($metric, $metricModificator);

			foreach ($metricModificator as $currentModificator)
			{
				if ($currentModificator['TYPE'] == 'BEFORE')
				{
					$metricDate->add('-1 DAY');
				}
				else if ($currentModificator['TYPE'] == 'AFTER')
				{
					$metricDate->add('1 DAY');
				}
				else if (in_array($currentModificator['TYPE'], Array('NEXT', 'PREVIOUS')))
				{
					if ($currentModificator['TYPE'] == 'NEXT')
					{
						$metricDate->add('NEXT '.$metric['TYPE']);
					}
					else
					{
						$metricDate->add('PREVIOUS '.$metric['TYPE']);
					}
				}
				else if ($currentModificator['TYPE'] == 'MIDDLEOF')
				{
					$metricTime = '14:00';
				}
				else if ($currentModificator['TYPE'] == 'STARTOF')
				{
					$metricTime = $timeOfStartDate;
				}
				else if (in_array($currentModificator['TYPE'], Array('MORNING', 'LUNCH', 'EVENING', 'HHMM')))
				{
					$metricTime = $currentModificator['VALUE'];
				}
				$modificator = true;

			}

			if (!$modificator)
			{
				$modificator = strtolower($metric['TYPE']) == strtolower($metricDate->format('l'))? 'NEXT ': '';
				$metricDate->add($modificator.$metric['TYPE']);
			}

			$result = new BitrixMainTypeDateTime($metricDate->format('Y-m-d').' '.$metricTime.':00', 'Y-m-d H:i:s');
		break;
	}

	return $result;
}