• Модуль: tasks
  • Путь к файлу: ~/bitrix/modules/tasks/classes/general/task.php
  • Класс: CTasks
  • Вызов: CTasks::getSqlForTimestamps
static function getSqlForTimestamps($key, $val, $userID, $sAliasPrefix, $bGetZombie)
{
	static $ts = null;        // some fixed timestamp of "now" (for consistency)

	if ($ts === null)
	{
		$ts = CTasksPerHitOption::getHitTimestamp();
	}

	$bTzWasDisabled = !CTimeZone::enabled();

	if ($bTzWasDisabled)
	{
		CTimeZone::enable();
	}

	// Adjust UNIX TS to "Bitrix timestamp"
	$tzOffset = CTimeZone::getOffset();
	$ts += $tzOffset;

	if ($bTzWasDisabled)
	{
		CTimeZone::disable();
	}

	$arSqlSearch = [];

	$arFilter = [
		'::LOGIC' => 'AND',
	];

	$key = ltrim($key);

	$res = CTasks::MkOperationFilter($key);
	$fieldName = mb_substr($res["FIELD"], 5, -3);    // Cutoff prefix "META:" and suffix "_TS"
	$cOperationType = $res["OPERATION"];

	$operationSymbol = mb_substr($key, 0, -1 * mb_strlen($res["FIELD"]));

	if (mb_substr($cOperationType, 0, 1) !== '#')
	{
		switch ($operationSymbol)
		{
			case '<':
				$operationCode = CTaskFilterCtrl::OP_STRICTLY_LESS;
				break;

			case '>':
				$operationCode = CTaskFilterCtrl::OP_STRICTLY_GREATER;
				break;

			case '<=':
				$operationCode = CTaskFilterCtrl::OP_LESS_OR_EQUAL;
				break;

			case '>=':
				$operationCode = CTaskFilterCtrl::OP_GREATER_OR_EQUAL;
				break;

			case '!=':
				$operationCode = CTaskFilterCtrl::OP_NOT_EQUAL;
				break;

			case '':
			case '=':
				$operationCode = CTaskFilterCtrl::OP_EQUAL;
				break;

			default:
				CTaskAssert::log(
					'Unknown operation code: ' .
					$operationSymbol .
					'; $key = ' .
					$key .
					'; it will be silently ignored, incorrect results expected',
					CTaskAssert::ELL_ERROR    // errors, incorrect results expected
				);

				return ($arSqlSearch);
				break;
		}
	}
	else
	{
		$operationCode = (int)mb_substr($cOperationType, 1);
	}

	$date1 = $date2 = $cOperationType1 = $cOperationType2 = null;

	// sometimes we can have DAYS in $val, not TIMESTAMP
	if (
		$operationCode != CTaskFilterCtrl::OP_DATE_NEXT_DAYS
		&& $operationCode
		!= CTaskFilterCtrl::OP_DATE_LAST_DAYS
	)
	{
		$val += $tzOffset;
	}

	// Convert cOperationType to format accepted by self::FilterCreate
	switch ($operationCode)
	{
		case CTaskFilterCtrl::OP_EQUAL:
		case CTaskFilterCtrl::OP_DATE_TODAY:
		case CTaskFilterCtrl::OP_DATE_YESTERDAY:
		case CTaskFilterCtrl::OP_DATE_TOMORROW:
		case CTaskFilterCtrl::OP_DATE_CUR_WEEK:
		case CTaskFilterCtrl::OP_DATE_PREV_WEEK:
		case CTaskFilterCtrl::OP_DATE_NEXT_WEEK:
		case CTaskFilterCtrl::OP_DATE_CUR_MONTH:
		case CTaskFilterCtrl::OP_DATE_PREV_MONTH:
		case CTaskFilterCtrl::OP_DATE_NEXT_MONTH:
		case CTaskFilterCtrl::OP_DATE_NEXT_DAYS:
		case CTaskFilterCtrl::OP_DATE_LAST_DAYS:
			$cOperationType1 = '>=';
			$cOperationType2 = '<=';
			break;

		case CTaskFilterCtrl::OP_LESS_OR_EQUAL:
			$cOperationType1 = '<=';
			break;

		case CTaskFilterCtrl::OP_GREATER_OR_EQUAL:
			$cOperationType1 = '>=';
			break;

		case CTaskFilterCtrl::OP_NOT_EQUAL:
			$cOperationType1 = '<';
			$cOperationType2 = '>';
			break;

		case CTaskFilterCtrl::OP_STRICTLY_LESS:
			$cOperationType1 = '<';
			break;

		case CTaskFilterCtrl::OP_STRICTLY_GREATER:
			$cOperationType1 = '>';
			break;

		default:
			CTaskAssert::log(
				'Unknown operation code: ' .
				$operationCode .
				'; $key = ' .
				$key .
				'; it will be silently ignored, incorrect results expected',
				CTaskAssert::ELL_ERROR    // errors, incorrect results expected
			);

			return ($arSqlSearch);
			break;
	}

	// Convert/generate dates
	$ts1 = $ts2 = null;
	switch ($operationCode)
	{
		case CTaskFilterCtrl::OP_DATE_TODAY:
			$ts1 = $ts2 = $ts;
			break;

		case CTaskFilterCtrl::OP_DATE_YESTERDAY:
			$ts1 = $ts2 = $ts - 86400;
			break;

		case CTaskFilterCtrl::OP_DATE_TOMORROW:
			$ts1 = $ts2 = $ts + 86400;
			break;

		case CTaskFilterCtrl::OP_DATE_CUR_WEEK:
			$weekDay = date('N');    // numeric representation of the day of the week (1 to 7)
			$ts1 = $ts - ($weekDay - 1) * 86400;
			$ts2 = $ts + (7 - $weekDay) * 86400;
			break;

		case CTaskFilterCtrl::OP_DATE_PREV_WEEK:
			$weekDay = date('N');    // numeric representation of the day of the week (1 to 7)
			$ts1 = $ts - ($weekDay - 1 + 7) * 86400;
			$ts2 = $ts - $weekDay * 86400;
			break;

		case CTaskFilterCtrl::OP_DATE_NEXT_WEEK:
			$weekDay = date('N');    // numeric representation of the day of the week (1 to 7)
			$ts1 = $ts + (7 - $weekDay + 1) * 86400;
			$ts2 = $ts + (7 - $weekDay + 7) * 86400;
			break;

		case CTaskFilterCtrl::OP_DATE_CUR_MONTH:
			$ts1 = mktime(0, 0, 0, date('n', $ts), 1, date('Y', $ts));
			$ts2 = mktime(23, 59, 59, date('n', $ts) + 1, 0, date('Y', $ts));
			break;

		case CTaskFilterCtrl::OP_DATE_PREV_MONTH:
			$ts1 = mktime(0, 0, 0, date('n', $ts) - 1, 1, date('Y', $ts));
			$ts2 = mktime(23, 59, 59, date('n', $ts), 0, date('Y', $ts));
			break;

		case CTaskFilterCtrl::OP_DATE_NEXT_MONTH:
			$ts1 = mktime(0, 0, 0, date('n', $ts) + 1, 1, date('Y', $ts));
			$ts2 = mktime(23, 59, 59, date('n', $ts) + 2, 0, date('Y', $ts));
			break;

		case CTaskFilterCtrl::OP_DATE_LAST_DAYS:
			$ts1 = $ts - ((int)$val) * 86400; // val in days
			$ts2 = $ts;
			break;

		case CTaskFilterCtrl::OP_DATE_NEXT_DAYS:
			$ts1 = $ts;
			$ts2 = $ts + ((int)$val) * 86400; // val in days
			break;

		case CTaskFilterCtrl::OP_GREATER_OR_EQUAL:
		case CTaskFilterCtrl::OP_LESS_OR_EQUAL:
		case CTaskFilterCtrl::OP_STRICTLY_LESS:
		case CTaskFilterCtrl::OP_STRICTLY_GREATER:
			$ts1 = $val;
			break;

		case CTaskFilterCtrl::OP_EQUAL:
			$ts1 = mktime(0, 0, 0, date('n', $val), date('j', $val), date('Y', $val));
			$ts2 = mktime(23, 59, 59, date('n', $val), date('j', $val), date('Y', $val));
			break;

		case CTaskFilterCtrl::OP_NOT_EQUAL:
			$ts1 = mktime(0, 0, 0, date('n', $val), date('j', $val), date('Y', $val));
			$ts2 = mktime(23, 59, 59, date('n', $val), date('j', $val), date('Y', $val));
			break;

		default:
			CTaskAssert::log(
				'Unknown operation code: ' .
				$operationCode .
				'; $key = ' .
				$key .
				'; it will be silently ignored, incorrect results expected',
				CTaskAssert::ELL_ERROR    // errors, incorrect results expected
			);

			return ($arSqlSearch);
			break;
	}

	if ($ts1)
	{
		$date1 = ConvertTimeStamp(mktime(0, 0, 0, date('n', $ts1), date('j', $ts1), date('Y', $ts1)), 'FULL');
	}

	if ($ts2)
	{
		$date2 = ConvertTimeStamp(mktime(23, 59, 59, date('n', $ts2), date('j', $ts2), date('Y', $ts2)), 'FULL');
	}

	if (($cOperationType1 !== null) && ($date1 !== null))
	{
		$arrayKey = $cOperationType1 . $fieldName;
		while (isset($arFilter[$arrayKey]))
		{
			$arrayKey = ' ' . $arrayKey;
		}

		$arFilter[$arrayKey] = $date1;
	}

	if (($cOperationType2 !== null) && ($date2 !== null))
	{
		$arrayKey = $cOperationType2 . $fieldName;
		while (isset($arFilter[$arrayKey]))
		{
			$arrayKey = ' ' . $arrayKey;
		}

		$arFilter[$arrayKey] = $date2;
	}

	$arSqlSearch[] = self::GetSqlByFilter($arFilter, $userID, $sAliasPrefix, $bGetZombie);

	return ($arSqlSearch);
}