/** * Overridden constructor. * * @param $time * time string, flexible format including timestamp. * @param $tz * PHP DateTimeZone object, string or NULL allowed, defaults to site timezone. * @param $format * PHP date() type format for parsing. Doesn't support timezones; if you have a timezone, send NULL * and the default constructor method will hopefully parse it. * $format is recommended in order to use negative or large years, which php's parser fails on. */ public function __construct($time = 'now', $tz = NULL, $format = NULL) { $this->timeOnly = FALSE; $this->dateOnly = FALSE; // Allow string timezones if (!empty($tz) && !is_object($tz)) { $tz = new DateTimeZone($tz); } elseif (empty($tz)) { $tz = date_default_timezone_object(); } // Special handling for Unix timestamps expressed in the local timezone. // Create a date object in UTC and convert it to the local timezone. // Don't try to turn things like '2010' with a format of 'Y' into a timestamp. if (is_numeric($time) && (empty($format) || $format == 'U')) { // Assume timestamp. $time = "@" . $time; $date = new DateObject($time, 'UTC'); if ($tz->getName() != 'UTC') { $date->setTimezone($tz); } $time = $date->format(DATE_FORMAT_DATETIME); $format = DATE_FORMAT_DATETIME; } if (is_array($time)) { // Assume we were passed an indexed array. if (empty($time['year']) && empty($time['month']) && empty($time['day'])) { $this->timeOnly = TRUE; } if (empty($time['hour']) && empty($time['minute']) && empty($time['second'])) { $this->dateOnly = TRUE; } $this->errors = $this->arrayErrors($time); // Make this into an ISO date, // forcing a full ISO date even if some values are missing. $time = $this->toISO($time, TRUE); // We checked for errors already, skip the step of parsing the input values. $format = NULL; } // The parse function will also set errors on the date parts. if (!empty($format)) { $arg = self::$allgranularity; $element = array_pop($arg); while (!$this->parse($time, $tz, $format) && $element != 'year') { $element = array_pop($arg); $format = date_limit_format($format, $arg); } if ($element == 'year') { return FALSE; } } elseif (is_string($time)) { // PHP < 5.3 doesn't like the GMT- notation for parsing timezones. $time = str_replace("GMT-", "-", $time); $time = str_replace("GMT+", "+", $time); // We are going to let the parent dateObject do a best effort attempt to turn this // string into a valid date. It might fail and we want to control the error messages. try { @parent::__construct($time, $tz); } catch (Exception $e) { $this->errors['date'] = $e; return; } $this->setGranularityFromTime($time, $tz); } // This tz was given as just an offset, which causes problems, // or the timezone was invalid. if (!$this->getTimezone() || !preg_match('/[a-zA-Z]/', $this->getTimezone()->getName())) { $this->setTimezone(new DateTimeZone("UTC")); } }
/** * Build a description of an iCal rule. * * Constructs a human-readable description of the rule. */ function date_repeat_rrule_description($rrule, $format = 'D M d Y') { // Empty or invalid value. if (empty($rrule) || !strstr($rrule, 'RRULE')) { return; } // Make sure there will be an empty description for any unused parts. $description = array('!interval' => '', '!byday' => '', '!bymonth' => '', '!count' => '', '!until' => '', '!except' => '', '!additional' => '', '!week_starts_on' => ''); $parts = self::date_repeat_split_rrule($rrule); $additions = $parts[2]; $exceptions = $parts[1]; $rrule = $parts[0]; $interval = self::INTERVAL_options(); switch ($rrule['FREQ']) { case 'WEEKLY': $description['!interval'] = format_plural($rrule['INTERVAL'], 'every week', 'every @count weeks') . ' '; break; case 'MONTHLY': $description['!interval'] = format_plural($rrule['INTERVAL'], 'every month', 'every @count months') . ' '; break; case 'YEARLY': $description['!interval'] = format_plural($rrule['INTERVAL'], 'every year', 'every @count years') . ' '; break; default: $description['!interval'] = format_plural($rrule['INTERVAL'], 'every day', 'every @count days') . ' '; break; } if (!empty($rrule['BYDAY'])) { $days = date_repeat_dow_day_options(); $counts = date_repeat_dow_count_options(); $results = array(); foreach ($rrule['BYDAY'] as $byday) { $day = substr($byday, -2); $count = intval(str_replace(' ' . $day, '', $byday)); if ($count = intval(str_replace(' ' . $day, '', $byday))) { $results[] = trim(t('!repeats_every_interval on the !date_order !day_of_week', array('!repeats_every_interval ' => '', '!date_order' => strtolower($counts[substr($byday, 0, 2)]), '!day_of_week' => $days[$day]))); } else { $results[] = trim(t('!repeats_every_interval every !day_of_week', array('!repeats_every_interval ' => '', '!day_of_week' => $days[$day]))); } } $description['!byday'] = implode(' ' . t('and') . ' ', $results); } if (!empty($rrule['BYMONTH'])) { if (sizeof($rrule['BYMONTH']) < 12) { $results = array(); $months = Yii::app()->getLocale()->getMonthNames(); foreach ($rrule['BYMONTH'] as $month) { $results[] = $months[$month]; } if (!empty($rrule['BYMONTHDAY'])) { $description['!bymonth'] = trim(t('!repeats_every_interval on the !month_days of !month_names', array('!repeats_every_interval ' => '', '!month_days' => implode(', ', $rrule['BYMONTHDAY']), '!month_names' => implode(', ', $results)))); } else { $description['!bymonth'] = trim(t('!repeats_every_interval on !month_names', array('!repeats_every_interval ' => '', '!month_names' => implode(', ', $results)))); } } } if ($rrule['INTERVAL'] < 1) { $rrule['INTERVAL'] = 1; } if (!empty($rrule['COUNT'])) { $description['!count'] = trim(t('!repeats_every_interval !count times', array('!repeats_every_interval ' => '', '!count' => $rrule['COUNT']))); } if (!empty($rrule['UNTIL'])) { $until = date_ical_date($rrule['UNTIL'], 'UTC'); date_timezone_set($until, date_default_timezone_object()); $description['!until'] = trim(t('!repeats_every_interval until !until_date', array('!repeats_every_interval ' => '', '!until_date' => date_format_date($until, 'custom', $format)))); } if ($exceptions) { $values = array(); foreach ($exceptions as $exception) { $values[] = date_format_date(date_ical_date($exception), 'custom', $format); } $description['!except'] = trim(t('!repeats_every_interval except !except_dates', array('!repeats_every_interval ' => '', '!except_dates' => implode(', ', $values)))); } if (!empty($rrule['WKST'])) { $day_names = date_repeat_dow_day_options(); $description['!week_starts_on'] = trim(t('!repeats_every_interval where the week start on !day_of_week', array('!repeats_every_interval ' => '', '!day_of_week' => $day_names[trim($rrule['WKST'])]))); } if ($additions) { $values = array(); foreach ($additions as $addition) { $values[] = date_format_date(date_ical_date($addition), 'custom', $format); } $description['!additional'] = trim(t('Also includes !additional_dates.', array('!additional_dates' => implode(', ', $values)))); } return t('Repeats !interval !bymonth !byday !count !until !except. !additional', $description); }
/** * Custom repeat rule theme function for dates. * * @see date_repeat_rrule_description(). */ function ringstedtheme_repeat_rrule_description($rrule, $format = 'd.M') { // Empty or invalid value. if (empty($rrule) || !strstr($rrule, 'RRULE')) { return; } module_load_include('inc', 'date_api', 'date_api_ical'); module_load_include('inc', 'date_repeat', 'date_repeat_calc'); $parts = date_repeat_split_rrule($rrule); $rrule = $parts[0]; if ($rrule['FREQ'] == 'NONE') { return; } // Make sure there will be an empty description for any unused parts. $description = array('!interval' => '', '!byday' => '', '!bymonth' => '', '!count' => '', '!until' => '', '!except' => '', '!additional' => '', '!week_starts_on' => ''); $interval = date_repeat_interval_options(); switch ($rrule['FREQ']) { case 'WEEKLY': if (isset($rrule['BYDAY'])) { $description['!interval'] = format_plural($rrule['INTERVAL'], '', 'every @count weeks') . ' '; } else { $description['!interval'] = format_plural($rrule['INTERVAL'], 'every week', 'every @count weeks') . ' '; } break; case 'MONTHLY': $description['!interval'] = format_plural($rrule['INTERVAL'], 'every month', 'every @count months') . ' '; break; case 'YEARLY': $description['!interval'] = format_plural($rrule['INTERVAL'], 'every year', 'every @count years') . ' '; break; default: $description['!interval'] = format_plural($rrule['INTERVAL'], 'every day', 'every @count days') . ' '; break; } if (!empty($rrule['BYDAY'])) { $days = date_repeat_dow_day_options(); $counts = date_repeat_dow_count_options(); $results = array(); $first_day = $rrule['BYDAY'][0]; foreach ($rrule['BYDAY'] as $byday) { // Get the numeric part of the BYDAY option, i.e. +3 from +3MO. $day = substr($byday, -2); $count = str_replace($day, '', $byday); if (!empty($count)) { // See if there is a 'pretty' option for this count, i.e. +1 => First. $order = array_key_exists($count, $counts) ? strtolower($counts[$count]) : $count; $results[] = trim(t('!repeats_every_interval on the !date_order !day_of_week', array('!repeats_every_interval ' => '', '!date_order' => $order, '!day_of_week' => strtolower($days[$day])))); } else { if ($first_day === $byday) { $results[] = trim(t('!repeats_every_interval every !day_of_week', array('!repeats_every_interval ' => '', '!day_of_week' => strtolower($days[$day])))); } else { $results[] = trim(t('!repeats_every_interval !day_of_week', array('!repeats_every_interval ' => '', '!day_of_week' => strtolower($days[$day])))); } } } $days_count = count($rrule['BYDAY']); if ($days_count > 2) { $last_day = array_pop($results); $description['!byday'] = implode(' , ', $results); $description['!byday'] .= ' ' . t('and') . ' ' . $last_day; } else { $description['!byday'] = implode(' ' . t('and') . ' ', $results); } } if (!empty($rrule['BYMONTH'])) { if (sizeof($rrule['BYMONTH']) < 12) { $results = array(); $months = date_month_names(); foreach ($rrule['BYMONTH'] as $month) { $results[] = $months[$month]; } if (!empty($rrule['BYMONTHDAY'])) { $description['!bymonth'] = trim(t('!repeats_every_interval on the !month_days of !month_names', array('!repeats_every_interval ' => '', '!month_days' => implode(', ', $rrule['BYMONTHDAY']), '!month_names' => implode(', ', $results)))); } else { $description['!bymonth'] = trim(t('!repeats_every_interval on !month_names', array('!repeats_every_interval ' => '', '!month_names' => implode(', ', $results)))); } } } if ($rrule['INTERVAL'] < 1) { $rrule['INTERVAL'] = 1; } if (!empty($rrule['COUNT'])) { $description['!count'] = trim(t('!repeats_every_interval !count times', array('!repeats_every_interval ' => '', '!count' => $rrule['COUNT']))); } if (!empty($rrule['UNTIL'])) { $until = date_ical_date($rrule['UNTIL'], 'UTC'); date_timezone_set($until, date_default_timezone_object()); $description['!until'] = trim(t('!repeats_every_interval until !until_date', array('!repeats_every_interval ' => '', '!until_date' => strtolower(date_format_date($until, 'custom', $format))))); } if (!empty($rrule['WKST'])) { $day_names = date_repeat_dow_day_options(); $description['!week_starts_on'] = trim(t('!repeats_every_interval where the week start on !day_of_week', array('!repeats_every_interval ' => '', '!day_of_week' => $day_names[trim($rrule['WKST'])]))); } return preg_replace('/\\s*\\./', '.', t('Repeats !interval !bymonth !byday !count !until !except. !additional', $description)); }