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;
}