• Модуль: dav
  • Путь к файлу: ~/bitrix/modules/dav/classes/general/icalendartimezone.php
  • Класс: CDavICalendarTimeZone
  • Вызов: CDavICalendarTimeZone::ParseVTimezone
static function ParseVTimezone(CDavICalendarComponent $vtimezone, $year)
{
	$result['time'] = 0;
	$rruleInterval = 0; // 0 undefined, 1 yearly, 12 monthly

	$t = self::ParseUtcOffset($vtimezone->GetPropertyValue('TZOFFSETFROM'));
	if ($t === null)
	{
		return false;
	}
	$result['from'] = ($t["hours"] * 60 * 60 + $t["minutes"] * 60) * ($t["ahead"] ? 1 : -1);

	$t = self::ParseUtcOffset($vtimezone->GetPropertyValue('TZOFFSETTO'));
	if ($t === null)
	{
		return false;
	}
	$result['to'] = ($t["hours"] * 60 * 60 + $t["minutes"] * 60) * ($t["ahead"] ? 1 : -1);

	$t = $vtimezone->GetPropertyValue('DTSTART');
	if ($t === null)
	{
		return false;
	}
	$switchTime = self::ParseDateTime($t);
	if (!is_int($switchTime))
	{
		return false;
	}

	$rrules = $vtimezone->GetPropertyValue('RRULE');
	if ($rrules === null)
	{
		$t = getdate($switchTime);
		$result['time'] = @gmmktime($t['hours'], $t['minutes'], $t['seconds'], $t['mon'], $t['mday'], $t['year']);
		return $result;
	}

	$switchYear = date("Y", $switchTime);
	if ($switchYear > $year)
	{
		return false;
	}

	$rrules = explode(';', $rrules);
	foreach ($rrules as $rrule)
	{
		$t = explode('=', $rrule);
		switch ($t[0])
		{
			case 'FREQ':
				switch($t[1])
				{
					case 'YEARLY':
						if ($rruleInterval === 12)
						{
							return false;
						}
						$rruleInterval = 1;
						break;
					case 'MONTHLY':
						if ($rruleInterval === 1)
						{
							return false;
						}
						$rruleInterval = 12;
						break;
					default:
						return false;
				}
				break;

			case 'INTERVAL':
				if ($rruleInterval && (int)$t[1] !== $rruleInterval)
				{
					return false;
				}
				$rruleInterval = (int)$t[1];
				if ($rruleInterval !== 1 && $rruleInterval !== 12)
				{
					return false;
				}
				break;

			case 'COUNT':
				if ($switchYear + (int)$t[1] < (int)$year)
				{
					return false;
				}
				break;

			case 'BYMONTH':
				$month = (int)$t[1];
				break;

			case 'BYDAY':
				$len = strspn($t[1], '1234567890-+');
				if ((int)$len === 0)
				{
					return false;
				}
				$weekday = mb_substr($t[1], $len);
				$weekdays = array(
					'SU' => 0,
					'MO' => 1,
					'TU' => 2,
					'WE' => 3,
					'TH' => 4,
					'FR' => 5,
					'SA' => 6
				);
				$weekday = $weekdays[$weekday];
				$which = (int)mb_substr($t[1], 0, $len);
				break;

			case 'UNTIL':
				if ((int)$year > (int)mb_substr($t[1], 0, 4))
				{
					return false;
				}
				break;
		}
	}

	if ($rruleInterval === 12)
	{
		$month = date("n", $switchTime);
	}

	if (empty($month) || !isset($weekday))
	{
		return false;
	}

	$switchTime = date('H:i:s', $switchTime);
	$switchTime = explode(':', $switchTime);

	$when = gmmktime($switchTime[0], $switchTime[1], $switchTime[2], $month, 1, $year);
	$firstOfMonthWeekday = (int)gmdate('w', $when);

	if ($weekday >= $firstOfMonthWeekday)
	{
		$weekday -= 7;
	}

	$when -= ($firstOfMonthWeekday - $weekday) * 60 * 60 * 24;

	if ($which < 0)
	{
		do
		{
			$when += 60*60*24*7;
		}
		while ((int)gmdate('m', $when) === (int)$month);
	}

	$when += $which * 60 * 60 * 24 * 7;

	$result['time'] = $when;

	return $result;
}