View source
<?php
define('DATE_ISO', 'date');
define('DATE_UNIX', 'datestamp');
define('DATE_DATETIME', 'datetime');
define('DATE_ARRAY', 'array');
define('DATE_OBJECT', 'object');
define('DATE_ICAL', 'ical');
define('DATE_FORMAT_ISO', "Y-m-d\\TH:i:s");
define('DATE_FORMAT_UNIX', "U");
define('DATE_FORMAT_DATETIME', "Y-m-d H:i:s");
define('DATE_FORMAT_ICAL', "Ymd\\THis");
define('DATE_FORMAT_ICAL_DATE', "Ymd");
define('DATE_FORMAT_DATE', 'Y-m-d');
define('DATE_REGEX_ISO', '/(\\d{4})?(-(\\d{2}))?(-(\\d{2}))?([T\\s](\\d{2}))?(:(\\d{2}))?(:(\\d{2}))?/');
define('DATE_REGEX_DATETIME', '/(\\d{4})-(\\d{2})-(\\d{2})\\s(\\d{2}):(\\d{2}):?(\\d{2})?/');
define('DATE_REGEX_LOOSE', '/(\\d{4})-?(\\d{1,2})-?(\\d{1,2})([T\\s]?(\\d{2}):?(\\d{2}):?(\\d{2})?(\\.\\d+)?(Z|[\\+\\-]\\d{2}:?\\d{2})?)?/');
define('DATE_REGEX_ICAL_DATE', '/(\\d{4})(\\d{2})(\\d{2})/');
define('DATE_REGEX_ICAL_DATETIME', '/(\\d{4})(\\d{2})(\\d{2})T(\\d{2})(\\d{2})(\\d{2})(Z)?/');
class DateObject extends DateTime {
public $granularity = array();
public $errors = array();
protected static $allgranularity = array(
'year',
'month',
'day',
'hour',
'minute',
'second',
'timezone',
);
private $_serialized_time;
private $_serialized_timezone;
public function __sleep() {
$this->_serialized_time = $this
->format('c');
$this->_serialized_timezone = $this
->getTimezone()
->getName();
return array(
'_serialized_time',
'_serialized_timezone',
);
}
public function __wakeup() {
$this
->__construct($this->_serialized_time, new DateTimeZone($this->_serialized_timezone));
}
public function __toString() {
return $this
->format(DATE_FORMAT_DATETIME) . ' ' . $this
->getTimeZone()
->getName();
}
public function __construct($time = 'now', $tz = NULL, $format = NULL) {
$this->timeOnly = FALSE;
$this->dateOnly = FALSE;
if (!empty($tz) && !is_object($tz)) {
$tz = new DateTimeZone($tz);
}
elseif (empty($tz)) {
$tz = date_default_timezone_object();
}
if (is_numeric($time) && (empty($format) || $format == 'U')) {
$time = "@" . $time;
if ($tz
->getName() != 'UTC') {
$date = new DateObject($time, 'UTC');
$date
->setTimezone($tz);
$time = $date
->format(DATE_FORMAT_DATETIME);
$format = DATE_FORMAT_DATETIME;
}
}
if (is_array($time)) {
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);
$time = $this
->toISO($time, TRUE);
$format = NULL;
}
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)) {
$time = str_replace("GMT-", "-", $time);
$time = str_replace("GMT+", "+", $time);
try {
@parent::__construct($time, $tz);
} catch (Exception $e) {
$this->errors['date'] = $e;
return;
}
$this
->setGranularityFromTime($time, $tz);
}
if (!$this
->getTimezone() || !preg_match('/[a-zA-Z]/', $this
->getTimezone()
->getName())) {
$this
->setTimezone(new DateTimeZone("UTC"));
}
}
public function merge(FeedsDateTime $other) {
$other_tz = $other
->getTimezone();
$this_tz = $this
->getTimezone();
$use_tz = $this
->hasGranularity('timezone') || !$other
->hasGranularity('timezone') ? $this_tz : $other_tz;
$this2 = clone $this;
$this2
->setTimezone($use_tz);
$other
->setTimezone($use_tz);
$val = $this2
->toArray(TRUE);
$otherval = $other
->toArray();
foreach (self::$allgranularity as $g) {
if ($other
->hasGranularity($g) && !$this2
->hasGranularity($g)) {
$this2
->addGranularity($g);
$val[$g] = $otherval[$g];
}
}
$other
->setTimezone($other_tz);
$this2
->setDate($val['year'], $val['month'], $val['day']);
$this2
->setTime($val['hour'], $val['minute'], $val['second']);
return $this2;
}
public function setTimezone($tz, $force = FALSE) {
if (version_compare(PHP_VERSION, '5.2.7', '<') && $tz == $this
->getTimezone()) {
$tz = new DateTimeZone($tz
->getName());
}
if (!$this
->hasTime() || !$this
->hasGranularity('timezone') || $force) {
$arr = $this
->toArray(TRUE);
parent::setTimezone($tz);
$this
->setDate($arr['year'], $arr['month'], $arr['day']);
$this
->setTime($arr['hour'], $arr['minute'], $arr['second']);
$this
->addGranularity('timezone');
return;
}
return parent::setTimezone($tz);
}
public function format($format, $force = FALSE) {
return parent::format($force ? $format : date_limit_format($format, $this->granularity));
}
public function addGranularity($g) {
$this->granularity[] = $g;
$this->granularity = array_unique($this->granularity);
}
public function removeGranularity($g) {
if ($key = array_search($g, $this->granularity)) {
unset($this->granularity[$key]);
}
}
public function hasGranularity($g = NULL) {
if ($g === NULL) {
$last = TRUE;
foreach (self::$allgranularity as $arg) {
if ($arg == 'timezone') {
continue;
}
if (in_array($arg, $this->granularity) && !$last) {
return FALSE;
}
$last = in_array($arg, $this->granularity);
}
return in_array('year', $this->granularity);
}
if (is_array($g)) {
foreach ($g as $gran) {
if (!in_array($gran, $this->granularity)) {
return FALSE;
}
}
return TRUE;
}
return in_array($g, $this->granularity);
}
public function validGranularity($granularity = NULL, $flexible = FALSE) {
return $this
->hasGranularity() && (!$granularity || $flexible || $this
->hasGranularity($granularity));
}
public function hasTime() {
return $this
->hasGranularity('hour');
}
public function completeDate() {
return $this->completeDate;
}
public function limitGranularity($gran) {
foreach ($this->granularity as $key => $val) {
if ($val != 'timezone' && !in_array($val, $gran)) {
unset($this->granularity[$key]);
}
}
}
protected function setGranularityFromTime($time, $tz) {
$this->granularity = array();
$temp = date_parse($time);
if ($time == 'now') {
$this->granularity = array(
'year',
'month',
'day',
'hour',
'minute',
'second',
);
}
else {
foreach (self::$allgranularity as $g) {
if (isset($temp[$g]) && is_numeric($temp[$g]) || $g == 'timezone' && (isset($temp['zone_type']) && $temp['zone_type'] > 0)) {
$this->granularity[] = $g;
}
}
}
if ($tz) {
$this
->addGranularity('timezone');
}
}
protected function parse($date, $tz, $format) {
$array = date_format_patterns();
foreach ($array as $key => $value) {
$patterns[] = "`(^|[^\\\\\\\\])" . $key . "`";
$repl1[] = '${1}(.)';
$repl2[] = '${1}(' . $value . ')';
}
$patterns[] = "`\\\\\\\\([" . implode(array_keys($array)) . "])`";
$repl1[] = '${1}';
$repl2[] = '${1}';
$format_regexp = preg_quote($format);
$regex1 = preg_replace($patterns, $repl1, $format_regexp, 1);
$regex1 = str_replace('A', '(.)', $regex1);
$regex1 = str_replace('a', '(.)', $regex1);
preg_match('`^' . $regex1 . '$`', stripslashes($format), $letters);
array_shift($letters);
$regex2 = preg_replace($patterns, $repl2, $format_regexp, 1);
$regex2 = str_replace('A', '(AM|PM)', $regex2);
$regex2 = str_replace('a', '(am|pm)', $regex2);
preg_match('`^' . $regex2 . '$`', $date, $values);
array_shift($values);
if (count($letters) != count($values)) {
return FALSE;
}
$this->granularity = array();
$final_date = array(
'hour' => 0,
'minute' => 0,
'second' => 0,
'month' => 1,
'day' => 1,
'year' => 0,
);
foreach ($letters as $i => $letter) {
$value = $values[$i];
switch ($letter) {
case 'd':
case 'j':
$final_date['day'] = intval($value);
$this
->addGranularity('day');
break;
case 'n':
case 'm':
$final_date['month'] = intval($value);
$this
->addGranularity('month');
break;
case 'F':
$array_month_long = array_flip(date_month_names());
$final_date['month'] = $array_month_long[$value];
$this
->addGranularity('month');
break;
case 'M':
$array_month = array_flip(date_month_names_abbr());
$final_date['month'] = $array_month[$value];
$this
->addGranularity('month');
break;
case 'Y':
$final_date['year'] = $value;
$this
->addGranularity('year');
break;
case 'y':
$year = $value;
$final_date['year'] = str_pad($year, 4, substr(date("Y"), 0, 2), STR_PAD_LEFT);
$this
->addGranularity('year');
break;
case 'a':
case 'A':
$ampm = strtolower($value);
break;
case 'g':
case 'h':
case 'G':
case 'H':
$final_date['hour'] = intval($value);
$this
->addGranularity('hour');
break;
case 'i':
$final_date['minute'] = intval($value);
$this
->addGranularity('minute');
break;
case 's':
$final_date['second'] = intval($value);
$this
->addGranularity('second');
break;
case 'U':
parent::__construct($value, $tz ? $tz : new DateTimeZone("UTC"));
$this
->addGranularity('year');
$this
->addGranularity('month');
$this
->addGranularity('day');
$this
->addGranularity('hour');
$this
->addGranularity('minute');
$this
->addGranularity('second');
return $this;
break;
}
}
if (isset($ampm) && $ampm == 'pm' && $final_date['hour'] < 12) {
$final_date['hour'] += 12;
}
elseif (isset($ampm) && $ampm == 'am' && $final_date['hour'] == 12) {
$final_date['hour'] -= 12;
}
parent::__construct('', $tz ? $tz : new DateTimeZone("UTC"));
if ($tz) {
$this
->addGranularity('timezone');
}
$final_date['year'] = intval($final_date['year']);
$this->errors += $this
->arrayErrors($final_date);
if (empty($final_date['year']) && empty($final_date['month']) && empty($final_date['day'])) {
$this->timeOnly = TRUE;
}
elseif (empty($this->errors)) {
$this
->setDate($final_date['year'], $final_date['month'], $final_date['day']);
}
if (!isset($final_date['hour']) && !isset($final_date['minute']) && !isset($final_date['second'])) {
$this->dateOnly = TRUE;
}
elseif (empty($this->errors)) {
$this
->setTime($final_date['hour'], $final_date['minute'], $final_date['second']);
}
return $this;
}
public function toArray($force = FALSE) {
return array(
'year' => $this
->format('Y', $force),
'month' => $this
->format('n', $force),
'day' => $this
->format('j', $force),
'hour' => intval($this
->format('H', $force)),
'minute' => intval($this
->format('i', $force)),
'second' => intval($this
->format('s', $force)),
'timezone' => $this
->format('e', $force),
);
}
public function toISO($arr, $full = FALSE) {
$arr += array(
'year' => '',
'month' => '',
'day' => '',
'hour' => '',
'minute' => '',
'second' => '',
);
$datetime = '';
if ($arr['year'] !== '') {
$datetime = date_pad(intval($arr['year']), 4);
if ($full || $arr['month'] !== '') {
$datetime .= '-' . date_pad(intval($arr['month']));
if ($full || $arr['day'] !== '') {
$datetime .= '-' . date_pad(intval($arr['day']));
}
}
}
if ($arr['hour'] !== '') {
$datetime .= $datetime ? 'T' : '';
$datetime .= date_pad(intval($arr['hour']));
if ($full || $arr['minute'] !== '') {
$datetime .= ':' . date_pad(intval($arr['minute']));
if ($full || $arr['second'] !== '') {
$datetime .= ':' . date_pad(intval($arr['second']));
}
}
}
return $datetime;
}
public function setFuzzyDate($date, $format = NULL, $default = 'first') {
$comp = new DateObject($date, $this
->getTimeZone()
->getName(), $format);
$arr = $comp
->toArray(TRUE);
foreach ($arr as $key => $value) {
$arr[$key] = $this
->forceValid($key, intval($value), $default, $arr['month'], $arr['year']);
}
$this
->setDate($arr['year'], $arr['month'], $arr['day']);
$this
->setTime($arr['hour'], $arr['minute'], $arr['second']);
}
protected function forceValid($part, $value, $default = 'first', $month = NULL, $year = NULL) {
$now = date_now();
switch ($part) {
case 'year':
$fallback = $now
->format('Y');
return !is_int($value) || empty($value) || $value < variable_get('date_min_year', 1) || $value > variable_get('date_max_year', 4000) ? $fallback : $value;
break;
case 'month':
$fallback = $default == 'first' ? 1 : $now
->format('n');
return !is_int($value) || empty($value) || $value <= 0 || $value > 12 ? $fallback : $value;
break;
case 'day':
$fallback = $default == 'first' ? 1 : $now
->format('j');
$max_day = isset($year) && isset($month) ? date_days_in_month($year, $month) : 31;
return !is_int($value) || empty($value) || $value <= 0 || $value > $max_day ? $fallback : $value;
break;
case 'hour':
$fallback = $default == 'first' ? 0 : $now
->format('G');
return !is_int($value) || $value < 0 || $value > 23 ? $fallback : $value;
break;
case 'minute':
$fallback = $default == 'first' ? 0 : $now
->format('i');
return !is_int($value) || $value < 0 || $value > 59 ? $fallback : $value;
break;
case 'second':
$fallback = $default == 'first' ? 0 : $now
->format('s');
return !is_int($value) || $value < 0 || $value > 59 ? $fallback : $value;
break;
}
}
public function arrayErrors($arr) {
$errors = array();
$now = date_now();
$default_month = !empty($arr['month']) ? $arr['month'] : $now
->format('n');
$default_year = !empty($arr['year']) ? $arr['year'] : $now
->format('Y');
foreach ($arr as $part => $value) {
$value = intval($value);
if (!empty($value) && $this
->forceValid($part, $value, 'now', $default_month, $default_year) != $value) {
switch ($part) {
case 'year':
$errors['year'] = t('The year is invalid.');
break;
case 'month':
$errors['month'] = t('The month is invalid.');
break;
case 'day':
$errors['day'] = t('The day is invalid.');
break;
case 'hour':
$errors['hour'] = t('The hour is invalid.');
break;
case 'minute':
$errors['minute'] = t('The minute is invalid.');
break;
case 'second':
$errors['second'] = t('The second is invalid.');
break;
}
}
}
return $errors;
}
public function difference($date2_in, $measure = 'seconds') {
$date1 = clone $this;
$date2 = clone $date2_in;
if (is_object($date1) && is_object($date2)) {
$diff = date_format($date2, 'U') - date_format($date1, 'U');
if ($diff == 0) {
return 0;
}
elseif ($diff < 0) {
$temp = $date2;
$date2 = $date1;
$date1 = $temp;
$diff = date_format($date2, 'U') - date_format($date1, 'U');
}
$year_diff = intval(date_format($date2, 'Y') - date_format($date1, 'Y'));
switch ($measure) {
case 'seconds':
return $diff;
case 'minutes':
return $diff / 60;
case 'hours':
return $diff / 3600;
case 'years':
return $year_diff;
case 'months':
$format = 'n';
$item1 = date_format($date1, $format);
$item2 = date_format($date2, $format);
if ($year_diff == 0) {
return intval($item2 - $item1);
}
else {
$item_diff = 12 - $item1;
$item_diff += intval(($year_diff - 1) * 12);
return $item_diff + $item2;
}
break;
case 'days':
$format = 'z';
$item1 = date_format($date1, $format);
$item2 = date_format($date2, $format);
if ($year_diff == 0) {
return intval($item2 - $item1);
}
else {
$item_diff = date_days_in_year($date1) - $item1;
for ($i = 1; $i < $year_diff; $i++) {
date_modify($date1, '+1 year');
$item_diff += date_days_in_year($date1);
}
return $item_diff + $item2;
}
break;
case 'weeks':
$week_diff = date_format($date2, 'W') - date_format($date1, 'W');
$year_diff = date_format($date2, 'o') - date_format($date1, 'o');
for ($i = 1; $i <= $year_diff; $i++) {
date_modify($date1, '+1 year');
$week_diff += date_iso_weeks_in_year($date1);
}
return $week_diff;
}
}
return NULL;
}
}
function date_db_type() {
return $GLOBALS['databases']['default']['default']['driver'];
}
function date_type_format($type) {
switch ($type) {
case DATE_ISO:
return DATE_FORMAT_ISO;
case DATE_UNIX:
return DATE_FORMAT_UNIX;
case DATE_DATETIME:
return DATE_FORMAT_DATETIME;
case DATE_ICAL:
return DATE_FORMAT_ICAL;
}
}
function date_api_init() {
drupal_add_css(drupal_get_path('module', 'date_api') . '/date.css', array(
'weight' => CSS_THEME,
));
}
function date_month_names_untranslated() {
static $month_names;
if (empty($month_names)) {
$month_names = array(
1 => 'January',
2 => 'February',
3 => 'March',
4 => 'April',
5 => 'May',
6 => 'June',
7 => 'July',
8 => 'August',
9 => 'September',
10 => 'October',
11 => 'November',
12 => 'December',
);
}
return $month_names;
}
function date_month_names($required = FALSE) {
$month_names = array();
foreach (date_month_names_untranslated() as $key => $month) {
$month_names[$key] = t($month, array(), array(
'context' => 'month_name',
));
}
$none = array(
'' => '',
);
return !$required ? $none + $month_names : $month_names;
}
function date_month_names_abbr($required = FALSE, $length = 3) {
$month_names = array();
foreach (date_month_names_untranslated() as $key => $month) {
$month_names[$key] = t(substr($month, 0, $length), array(), array(
'context' => 'month_abbr',
));
}
$none = array(
'' => '',
);
return !$required ? $none + $month_names : $month_names;
}
function date_week_days_untranslated($refresh = TRUE) {
static $weekdays;
if ($refresh || empty($weekdays)) {
$weekdays = array(
0 => 'Sunday',
1 => 'Monday',
2 => 'Tuesday',
3 => 'Wednesday',
4 => 'Thursday',
5 => 'Friday',
6 => 'Saturday',
);
}
return $weekdays;
}
function date_week_days($required = FALSE, $refresh = TRUE) {
$weekdays = array();
foreach (date_week_days_untranslated() as $key => $day) {
$weekdays[$key] = t($day, array(), array(
'context' => 'day_name',
));
}
$none = array(
'' => '',
);
return !$required ? $none + $weekdays : $weekdays;
}
function date_week_days_abbr($required = FALSE, $refresh = TRUE, $length = 3) {
$weekdays = array();
switch ($length) {
case 1:
$context = 'day_abbr1';
break;
case 2:
$context = 'day_abbr2';
break;
default:
$context = 'day_abbr';
break;
}
foreach (date_week_days_untranslated() as $key => $day) {
$weekdays[$key] = t(substr($day, 0, $length), array(), array(
'context' => $context,
));
}
$none = array(
'' => '',
);
return !$required ? $none + $weekdays : $weekdays;
}
function date_week_days_ordered($weekdays) {
if (variable_get('date_first_day', 1) > 0) {
for ($i = 1; $i <= variable_get('date_first_day', 1); $i++) {
$last = array_shift($weekdays);
array_push($weekdays, $last);
}
}
return $weekdays;
}
function date_years($min = 0, $max = 0, $required = FALSE) {
if (empty($min)) {
$min = intval(date('Y', REQUEST_TIME) - 3);
}
if (empty($max)) {
$max = intval(date('Y', REQUEST_TIME) + 3);
}
$none = array(
0 => '',
);
return !$required ? $none + drupal_map_assoc(range($min, $max)) : drupal_map_assoc(range($min, $max));
}
function date_days($required = FALSE, $month = NULL, $year = NULL) {
if (!empty($month) && !empty($year)) {
$date = new DateObject($year . '-' . $month . '-01 00:00:00', 'UTC');
$max = $date
->format('t');
}
if (empty($max)) {
$max = 31;
}
$none = array(
0 => '',
);
return !$required ? $none + drupal_map_assoc(range(1, $max)) : drupal_map_assoc(range(1, $max));
}
function date_hours($format = 'H', $required = FALSE) {
$hours = array();
if ($format == 'h' || $format == 'g') {
$min = 1;
$max = 12;
}
else {
$min = 0;
$max = 23;
}
for ($i = $min; $i <= $max; $i++) {
$hours[$i] = $i < 10 && ($format == 'H' || $format == 'h') ? "0{$i}" : $i;
}
$none = array(
'' => '',
);
return !$required ? $none + $hours : $hours;
}
function date_minutes($format = 'i', $required = FALSE, $increment = 1) {
$minutes = array();
if (empty($increment)) {
$increment = 1;
}
for ($i = 0; $i < 60; $i += $increment) {
$minutes[$i] = $i < 10 && $format == 'i' ? "0{$i}" : $i;
}
$none = array(
'' => '',
);
return !$required ? $none + $minutes : $minutes;
}
function date_seconds($format = 's', $required = FALSE, $increment = 1) {
$seconds = array();
if (empty($increment)) {
$increment = 1;
}
for ($i = 0; $i < 60; $i += $increment) {
$seconds[$i] = $i < 10 && $format == 's' ? "0{$i}" : $i;
}
$none = array(
'' => '',
);
return !$required ? $none + $seconds : $seconds;
}
function date_ampm($required = FALSE) {
$none = array(
'' => '',
);
$ampm = array(
'am' => t('am', array(), array(
'context' => 'ampm',
)),
'pm' => t('pm', array(), array(
'context' => 'ampm',
)),
);
return !$required ? $none + $ampm : $ampm;
}
function date_format_patterns($strict = FALSE) {
return array(
'd' => '\\d{' . ($strict ? '2' : '1,2') . '}',
'm' => '\\d{' . ($strict ? '2' : '1,2') . '}',
'h' => '\\d{' . ($strict ? '2' : '1,2') . '}',
'H' => '\\d{' . ($strict ? '2' : '1,2') . '}',
'i' => '\\d{' . ($strict ? '2' : '1,2') . '}',
's' => '\\d{' . ($strict ? '2' : '1,2') . '}',
'j' => '\\d{1,2}',
'N' => '\\d',
'S' => '\\w{2}',
'w' => '\\d',
'z' => '\\d{1,3}',
'W' => '\\d{1,2}',
'n' => '\\d{1,2}',
't' => '\\d{2}',
'L' => '\\d',
'o' => '\\d{4}',
'Y' => '-?\\d{1,6}',
'y' => '\\d{2}',
'B' => '\\d{3}',
'g' => '\\d{1,2}',
'G' => '\\d{1,2}',
'e' => '\\w*',
'I' => '\\d',
'T' => '\\w*',
'U' => '\\d*',
'z' => '[+-]?\\d*',
'O' => '[+-]?\\d{4}',
'D' => '\\S{3,4}',
'l' => '\\S*',
'M' => '\\S{3,4}',
'F' => '\\S*',
'P' => '[+-]?\\d{2}\\:\\d{2}',
'O' => '[+-]\\d{4}',
'c' => '(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})([+-]?\\d{2}\\:\\d{2})',
'r' => '(\\w{3}), (\\d{2})\\s(\\w{3})\\s(\\d{2,4})\\s(\\d{2}):(\\d{2}):(\\d{2})([+-]?\\d{4})?',
);
}
function date_granularity_names() {
return array(
'year' => t('Year', array(), array(
'context' => 'datetime',
)),
'month' => t('Month', array(), array(
'context' => 'datetime',
)),
'day' => t('Day', array(), array(
'context' => 'datetime',
)),
'hour' => t('Hour', array(), array(
'context' => 'datetime',
)),
'minute' => t('Minute', array(), array(
'context' => 'datetime',
)),
'second' => t('Second', array(), array(
'context' => 'datetime',
)),
);
}
function date_granularity_sorted($granularity) {
return array_intersect(array(
'year',
'month',
'day',
'hour',
'minute',
'second',
), $granularity);
}
function date_granularity_array_from_precision($precision) {
$granularity_array = array(
'year',
'month',
'day',
'hour',
'minute',
'second',
);
switch ($precision) {
case 'year':
return array_slice($granularity_array, -6);
case 'month':
return array_slice($granularity_array, -5);
case 'day':
return array_slice($granularity_array, -4);
case 'hour':
return array_slice($granularity_array, -3);
case 'minute':
return array_slice($granularity_array, -2);
default:
return $granularity_array;
}
}
function date_granularity_precision($granularity_array) {
$input = clone $granularity_array;
return array_pop($input);
}
function date_granularity_format($granularity) {
if (is_array($granularity)) {
$granularity = date_granularity_precision($granularity);
}
$format = 'Y-m-d H:i:s';
switch ($granularity) {
case 'year':
return substr($format, 0, 1);
case 'month':
return substr($format, 0, 3);
case 'day':
return substr($format, 0, 5);
case 'hour':
return substr($format, 0, 7);
case 'minute':
return substr($format, 0, 9);
default:
return $format;
}
}
function date_timezone_names($required = FALSE, $refresh = FALSE) {
static $zonenames;
if (empty($zonenames) || $refresh) {
$cached = cache_get('date_timezone_identifiers_list');
$zonenames = !empty($cached) ? $cached->data : array();
if ($refresh || empty($cached) || empty($zonenames)) {
$data = timezone_identifiers_list();
asort($data);
foreach ($data as $delta => $zone) {
if (preg_match('!^((Africa|America|Antarctica|Arctic|Asia|Atlantic|Australia|Europe|Indian|Pacific)/|UTC$)!', $zone)) {
$zonenames[$zone] = $zone;
}
}
if (!empty($zonenames)) {
cache_set('date_timezone_identifiers_list', $zonenames);
}
}
foreach ($zonenames as $zone) {
$zonenames[$zone] = t('!timezone', array(
'!timezone' => $zone,
));
}
}
$none = array(
'' => '',
);
return !$required ? $none + $zonenames : $zonenames;
}
function date_timezone_abbr($refresh = FALSE) {
$cached = cache_get('date_timezone_abbreviations');
$data = isset($cached->data) ? $cached->data : array();
if (empty($data) || $refresh) {
$data = array_keys(timezone_abbreviations_list());
cache_set('date_timezone_abbreviations', $data);
}
return $data;
}
function date_format_date($date, $type = 'medium', $format = '', $langcode = NULL) {
if (empty($date)) {
return '';
}
switch ($type) {
case 'small':
case 'short':
$format = variable_get('date_format_short', 'm/d/Y - H:i');
break;
case 'large':
case 'long':
$format = variable_get('date_format_long', 'l, F j, Y - H:i');
break;
case 'custom':
$format = $format;
break;
case 'medium':
default:
$format = variable_get('date_format_medium', 'D, m/d/Y - H:i');
}
$format = date_limit_format($format, $date->granularity);
$max = strlen($format);
$datestring = '';
for ($i = 0; $i < $max; $i++) {
$c = $format[$i];
switch ($c) {
case 'l':
$datestring .= t($date
->format('l'), array(), array(
'context' => 'day_name',
'langcode' => $langcode,
));
break;
case 'D':
$datestring .= t($date
->format('D'), array(), array(
'context' => 'day_abbr',
'langcode' => $langcode,
));
break;
case 'F':
$datestring .= t($date
->format('F'), array(), array(
'context' => 'month_name',
'langcode' => $langcode,
));
break;
case 'M':
$datestring .= t($date
->format('M'), array(), array(
'context' => 'month_abbr',
'langcode' => $langcode,
));
break;
case 'A':
case 'a':
$datestring .= t($date
->format($c), array(), array(
'context' => 'ampm',
'langcode' => $langcode,
));
break;
case 'e':
case 'T':
$datestring .= t($date
->format($c));
break;
case 'O':
$datestring .= sprintf('%s%02d%02d', date_offset_get($date) < 0 ? '-' : '+', abs(date_offset_get($date) / 3600), abs(date_offset_get($date) % 3600) / 60);
break;
case 'P':
$datestring .= sprintf('%s%02d:%02d', date_offset_get($date) < 0 ? '-' : '+', abs(date_offset_get($date) / 3600), abs(date_offset_get($date) % 3600) / 60);
break;
case 'Z':
$datestring .= date_offset_get($date);
break;
case '\\':
$datestring .= $format[++$i];
break;
case 'r':
$datestring .= date_format_date($date, 'custom', 'D, d M Y H:i:s O', $langcode);
break;
default:
if (strpos('BdcgGhHiIjLmnNosStTuUwWYyz', $c) !== FALSE) {
$datestring .= $date
->format($c);
}
else {
$datestring .= $c;
}
}
}
return $datestring;
}
function date_format_interval($date, $granularity = 2) {
if (empty($date)) {
return NULL;
}
$interval = REQUEST_TIME - $date
->format('U');
if ($interval > 0) {
return t('!time ago', array(
'!time' => format_interval($interval, $granularity),
));
}
else {
return format_interval(abs($interval), $granularity);
}
}
function date_now($timezone = NULL) {
return new DateObject('now', $timezone);
}
function date_timezone_is_valid($timezone) {
static $timezone_names;
if (empty($timezone_names)) {
$timezone_names = array_keys(date_timezone_names(TRUE));
}
if (!in_array($timezone, $timezone_names)) {
return FALSE;
}
return TRUE;
}
function date_default_timezone($check_user = TRUE) {
global $user;
if ($check_user && variable_get('configurable_timezones', 1) && !empty($user->timezone)) {
return $user->timezone;
}
else {
$default = variable_get('date_default_timezone', '');
return empty($default) ? 'UTC' : $default;
}
}
function date_default_timezone_object($check_user = TRUE) {
$timezone = date_default_timezone($check_user);
return timezone_open(date_default_timezone($check_user));
}
function date_days_in_month($year, $month) {
$datetime = date_pad($year, 4) . '-' . date_pad($month) . '-15 00:00:00';
$date = new DateObject($datetime);
return $date
->format('t');
}
function date_days_in_year($date = NULL) {
if (empty($date)) {
$date = date_now();
}
elseif (!is_object($date)) {
$date = new DateObject($date);
}
if (is_object($date)) {
if ($date
->format('L')) {
return 366;
}
else {
return 365;
}
}
return NULL;
}
function date_iso_weeks_in_year($date = NULL) {
if (empty($date)) {
$date = date_now();
}
elseif (!is_object($date)) {
$date = new DateObject($date);
}
if (is_object($date)) {
date_date_set($date, $date
->format('Y'), 12, 28);
return $date
->format('W');
}
return NULL;
}
function date_day_of_week($date = NULL) {
if (empty($date)) {
$date = date_now();
}
elseif (!is_object($date)) {
$date = new DateObject($date);
}
if (is_object($date)) {
return $date
->format('w');
}
return NULL;
}
function date_day_of_week_name($date = NULL, $abbr = TRUE) {
if (!is_object($date)) {
$date = new DateObject($date);
}
$dow = date_day_of_week($date);
$days = $abbr ? date_week_days_abbr() : date_week_days();
return $days[$dow];
}
function date_week_range($week, $year) {
if (variable_get('date_api_use_iso8601', FALSE)) {
return date_iso_week_range($week, $year);
}
$min_date = new DateObject($year . '-01-01 00:00:00');
$min_date
->setTimezone(date_default_timezone_object());
date_modify($min_date, '+' . strval(7 * ($week - 1)) . ' days');
$first_day = variable_get('date_first_day', 1);
$day_wday = date_format($min_date, 'w');
date_modify($min_date, '-' . strval((7 + $day_wday - $first_day) % 7) . ' days');
$max_date = clone $min_date;
date_modify($max_date, '+7 days');
if (date_format($min_date, 'Y') != $year) {
$min_date = new DateObject($year . '-01-01 00:00:00');
}
return array(
$min_date,
$max_date,
);
}
function date_iso_week_range($week, $year) {
$min_date = new DateObject($year - 1 . '-12-28 00:00:00');
date_timezone_set($min_date, date_default_timezone_object());
date_modify($min_date, '+1 Monday');
if ($week > 1) {
date_modify($min_date, '+ ' . ($week - 1) . ' weeks');
}
$max_date = clone $min_date;
date_modify($max_date, '+7 days');
return array(
$min_date,
$max_date,
);
}
function date_weeks_in_year($year) {
$date = new DateObject($year + 1 . '-01-01 12:00:00', 'UTC');
date_modify($date, '-1 day');
return date_week($date
->format('Y-m-d'));
}
function date_week($date) {
$date = substr($date, 0, 10);
$parts = explode('-', $date);
$date = new DateObject($date . ' 12:00:00', 'UTC');
if (variable_get('date_api_use_iso8601', FALSE)) {
return intval($date
->format('W'));
}
$year_date = new DateObject($parts[0] . '-01-01 12:00:00', 'UTC');
$week = intval($date
->format('W'));
$year_week = intval(date_format($year_date, 'W'));
$date_year = intval($date
->format('o'));
if ($date_year > intval($parts[0])) {
$last_date = clone $date;
date_modify($last_date, '-7 days');
$week = date_format($last_date, 'W') + 1;
}
elseif ($date_year < intval($parts[0])) {
$week = 0;
}
if ($year_week != 1) {
$week++;
}
$iso_first_day = 1 + (variable_get('date_first_day', 1) + 6) % 7;
if (intval($date
->format('N')) < $iso_first_day) {
$week--;
}
if (intval(date_format($year_date, 'N')) < $iso_first_day) {
$week++;
}
return $week;
}
function date_pad($value, $size = 2) {
return sprintf("%0" . $size . "d", $value);
}
function date_has_time($granularity) {
if (!is_array($granularity)) {
$granularity = array();
}
return sizeof(array_intersect($granularity, array(
'hour',
'minute',
'second',
))) > 0 ? TRUE : FALSE;
}
function date_has_date($granularity) {
if (!is_array($granularity)) {
$granularity = array();
}
return sizeof(array_intersect($granularity, array(
'year',
'month',
'day',
))) > 0 ? TRUE : FALSE;
}
function date_limit_format($format, $granularity) {
$replace = array(
'\\-' => '-',
'\\:' => ':',
"\\'" => "'",
'\\. ' => ' . ',
'\\,' => ',',
);
$format = strtr($format, $replace);
if (!date_has_time($granularity) || !date_has_date($granularity)) {
$format = str_replace('\\T', ' ', $format);
$format = str_replace('T', ' ', $format);
}
$regex = array();
if (!date_has_time($granularity)) {
$regex[] = '((?<!\\\\)[a|A])';
}
foreach (date_nongranularity($granularity) as $element) {
switch ($element) {
case 'year':
$regex[] = '([\\-/\\.,:]?\\s?(?<!\\\\)[Yy])';
break;
case 'day':
$regex[] = '([\\-/\\.,:]?\\s?(?<!\\\\)[l|D|d|dS|j|jS]{1,2})';
break;
case 'month':
$regex[] = '([\\-/\\.,:]?\\s?(?<!\\\\)[FMmn])';
break;
case 'hour':
$regex[] = '([\\-/\\.,:]?\\s?(?<!\\\\)[HhGg])';
break;
case 'minute':
$regex[] = '([\\-/\\.,:]?\\s?(?<!\\\\)[i])';
break;
case 'second':
$regex[] = '([\\-/\\.,:]?\\s?(?<!\\\\)[s])';
break;
case 'timezone':
$regex[] = '([\\-/\\.,:]?\\s?(?<!\\\\)[TOZPe])';
break;
}
}
$regex[] = '(\\(\\))';
$regex[] = '(\\[\\])';
$regex[] = '(\\|\\|)';
$format = trim(preg_replace($regex, array(), $format));
$format = preg_replace('`^([\\-/\\.,:\'])`', '', $format);
$format = preg_replace('([\\-/\\.,:\']$)', '', $format);
$format = preg_replace('(\\$)', '', $format);
$format = trim($format);
if (!($test = trim(preg_replace('(\\\\\\w{1})', '', $format)))) {
return '';
}
return $format;
}
function date_format_order($format) {
$order = array();
if (empty($format)) {
return $order;
}
$max = strlen($format);
for ($i = 0; $i <= $max; $i++) {
if (!isset($format[$i])) {
break;
}
$c = $format[$i];
switch ($c) {
case 'd':
case 'j':
$order[] = 'day';
break;
case 'F':
case 'M':
case 'm':
case 'n':
$order[] = 'month';
break;
case 'Y':
case 'y':
$order[] = 'year';
break;
case 'g':
case 'G':
case 'h':
case 'H':
$order[] = 'hour';
break;
case 'i':
$order[] = 'minute';
break;
case 's':
$order[] = 'second';
break;
}
}
return $order;
}
function date_nongranularity($granularity) {
return array_diff(array(
'year',
'month',
'day',
'hour',
'minute',
'second',
'timezone',
), (array) $granularity);
}
function date_api_element_info() {
module_load_include('inc', 'date_api', 'date_api_elements');
return _date_api_element_info();
}
function date_api_theme() {
$path = drupal_get_path('module', 'date_api');
$base = array(
'file' => 'theme.inc',
'path' => "{$path}/theme",
);
return array(
'date_nav_title' => $base + array(
'variables' => array(
'granularity' => NULL,
'view' => NULL,
'link' => NULL,
'format' => NULL,
),
),
'date_vcalendar' => $base + array(
'variables' => array(
'events' => NULL,
'calname' => NULL,
),
),
'date_vevent' => $base + array(
'variables' => array(
'event' => NULL,
),
),
'date_valarm' => $base + array(
'variables' => array(
'alarm' => NULL,
),
),
'date_timezone' => $base + array(
'render element' => 'element',
),
'date_select' => $base + array(
'render element' => 'element',
),
'date_text' => $base + array(
'render element' => 'element',
),
'date_select_element' => $base + array(
'render element' => 'element',
),
'date_textfield_element' => $base + array(
'render element' => 'element',
),
'date_date_part_hour_prefix' => $base + array(
'render element' => 'element',
),
'date_part_minsec_prefix' => $base + array(
'render element' => 'element',
),
'date_part_label_year' => $base + array(
'variables' => array(
'date_part' => NULL,
'element' => NULL,
),
),
'date_part_label_month' => $base + array(
'variables' => array(
'date_part' => NULL,
'element' => NULL,
),
),
'date_part_label_day' => $base + array(
'variables' => array(
'date_part' => NULL,
'element' => NULL,
),
),
'date_part_label_hour' => $base + array(
'variables' => array(
'date_part' => NULL,
'element' => NULL,
),
),
'date_part_label_minute' => $base + array(
'variables' => array(
'date_part' => NULL,
'element' => NULL,
),
),
'date_part_label_second' => $base + array(
'variables' => array(
'date_part' => NULL,
'element' => NULL,
),
),
'date_part_label_ampm' => $base + array(
'variables' => array(
'date_part' => NULL,
'element' => NULL,
),
),
'date_part_label_timezone' => $base + array(
'variables' => array(
'date_part' => NULL,
'element' => NULL,
),
),
'date_views_filter_form' => $base + array(
'template' => 'date-views-filter-form',
'render element' => 'form',
),
'date_calendar_day' => $base + array(
'variables' => array(
'date' => NULL,
),
),
'date_time_ago' => $base + array(
'variables' => array(
'start_date' => NULL,
'end_date' => NULL,
'interval' => NULL,
),
),
);
}
function date_api_set_db_timezone($offset = '+00:00') {
module_load_include('inc', 'date_api', 'date_api_sql');
$handler = new date_sql_handler();
return $handler
->set_db_timezone($offset);
}
function date_get_timezone($handling, $timezone = '') {
switch ($handling) {
case 'date':
$timezone = !empty($timezone) ? $timezone : date_default_timezone();
break;
case 'utc':
$timezone = 'UTC';
break;
default:
$timezone = date_default_timezone();
}
return $timezone > '' ? $timezone : date_default_timezone();
}
function date_get_timezone_db($handling, $timezone = '') {
return 'UTC';
}
function date_order_translated() {
return array(
'+1' => t('First', array(), array(
'context' => 'date_order',
)),
'+2' => t('Second', array(), array(
'context' => 'date_order',
)),
'+3' => t('Third', array(), array(
'context' => 'date_order',
)),
'+4' => t('Fourth', array(), array(
'context' => 'date_order',
)),
'+5' => t('Fifth', array(), array(
'context' => 'date_order',
)),
'-1' => t('Last', array(), array(
'context' => 'date_order_reverse',
)),
'-2' => t('Next to last', array(), array(
'context' => 'date_order_reverse',
)),
'-3' => t('Third from last', array(), array(
'context' => 'date_order_reverse',
)),
'-4' => t('Fourth from last', array(), array(
'context' => 'date_order_reverse',
)),
'-5' => t('Fifth from last', array(), array(
'context' => 'date_order_reverse',
)),
);
}
function date_order() {
return array(
'+1' => 'First',
'+2' => 'Second',
'+3' => 'Third',
'+4' => 'Fourth',
'+5' => 'Fifth',
'-1' => 'Last',
'-2' => '-2',
'-3' => '-3',
'-4' => '-4',
'-5' => '-5',
);
}
function date_range_valid($string) {
$matches = preg_match('@\\-[0-9]*:[\\+|\\-][0-9]*@', $string);
return $matches < 1 ? FALSE : TRUE;
}
function date_range_years($string, $date = NULL) {
$this_year = date_format(date_now(), 'Y');
list($min_year, $max_year) = explode(':', $string);
$plus_pattern = '@[\\+|\\-][0-9]{1,4}@';
$year_pattern = '@[0-9]{4}@';
if (!preg_match($year_pattern, $min_year, $matches)) {
if (preg_match($plus_pattern, $min_year, $matches)) {
$min_year = $this_year + $matches[0];
}
else {
$min_year = $this_year;
}
}
if (!preg_match($year_pattern, $max_year, $matches)) {
if (preg_match($plus_pattern, $max_year, $matches)) {
$max_year = $this_year + $matches[0];
}
else {
$max_year = $this_year;
}
}
if ($min_year > $max_year) {
$temp = $max_year;
$max_year = $min_year;
$min_year = $temp;
}
$value_year = is_object($date) ? $date
->format('Y') : '';
if (!empty($value_year)) {
$min_year = min($value_year, $min_year);
$max_year = max($value_year, $max_year);
}
return array(
$min_year,
$max_year,
);
}
function date_range_string($years) {
$this_year = date_format(date_now(), 'Y');
if ($years[0] < $this_year) {
$min = '-' . ($this_year - $years[0]);
}
else {
$min = '+' . ($years[0] - $this_year);
}
if ($years[1] < $this_year) {
$max = '-' . ($this_year - $years[1]);
}
else {
$max = '+' . ($years[1] - $this_year);
}
return $min . ':' . $max;
}
function date_api_database_info($field) {
$data = $field['storage']['details']['sql'][FIELD_LOAD_CURRENT];
$db_info = array(
'columns' => $data,
);
$current_table = _field_sql_storage_tablename($field);
$revision_table = _field_sql_storage_revision_tablename($field);
$db_info['table'] = $current_table;
return $db_info;
}
function date_api_form_system_regional_settings_alter(&$form, $form_state, $form_id = 'system_date_time_settings') {
$form['locale']['date_api_use_iso8601'] = array(
'#type' => 'checkbox',
'#title' => t('Use ISO-8601 week numbers'),
'#default_value' => variable_get('date_api_use_iso8601', FALSE),
'#description' => t('IMPORTANT! If checked, First day of week MUST be set to Monday'),
);
$form['#validate'][] = 'date_api_form_system_settings_validate';
$form = system_settings_form($form);
}
function date_api_form_system_settings_validate(&$form, &$form_state) {
$form_values = $form_state['values'];
if ($form_values['date_api_use_iso8601'] && $form_values['date_first_day'] != 1) {
form_set_error('date_first_day', t('When using ISO-8601 week numbers, the first day of the week must be set to Monday.'));
}
}
function date_format_type_options() {
$options = array();
$format_types = system_get_date_types();
if (!empty($format_types)) {
foreach ($format_types as $type => $type_info) {
$options[$type] = $type_info['title'];
}
}
return $options;
}
function date_is_all_day($string1, $string2, $granularity = 'second', $increment = 1) {
if (empty($string1) || empty($string2)) {
return FALSE;
}
elseif (!in_array($granularity, array(
'hour',
'minute',
'second',
))) {
return FALSE;
}
preg_match('/([0-9]{4}-[0-9]{2}-[0-9]{2}) (([0-9]{2}):([0-9]{2}):([0-9]{2}))/', $string1, $matches);
$count = count($matches);
$date1 = $count > 1 ? $matches[1] : '';
$time1 = $count > 2 ? $matches[2] : '';
$hour1 = $count > 3 ? intval($matches[3]) : 0;
$min1 = $count > 4 ? intval($matches[4]) : 0;
$sec1 = $count > 5 ? intval($matches[5]) : 0;
preg_match('/([0-9]{4}-[0-9]{2}-[0-9]{2}) (([0-9]{2}):([0-9]{2}):([0-9]{2}))/', $string2, $matches);
$count = count($matches);
$date2 = $count > 1 ? $matches[1] : '';
$time2 = $count > 2 ? $matches[2] : '';
$hour2 = $count > 3 ? intval($matches[3]) : 0;
$min2 = $count > 4 ? intval($matches[4]) : 0;
$sec2 = $count > 5 ? intval($matches[5]) : 0;
if (empty($date1) || empty($date2) || $date1 != $date2) {
return FALSE;
}
if (empty($time1) || empty($time2)) {
return FALSE;
}
$tmp = date_seconds('s', TRUE, $increment);
$max_seconds = intval(array_pop($tmp));
$tmp = date_minutes('i', TRUE, $increment);
$max_minutes = intval(array_pop($tmp));
switch ($granularity) {
case 'second':
$min_match = $time1 == '00:00:00' || $hour1 == 0 && $min1 == 0 && $sec1 == 0;
$max_match = $time2 == '00:00:00' || $hour2 == 23 && $min2 == $max_minutes && $sec2 == $max_seconds || $hour1 == 0 && $hour2 == 0 && $min1 == 0 && $min2 == 0 && $sec1 == 0 && $sec2 == 0;
break;
case 'minute':
$min_match = $time1 == '00:00:00' || $hour1 == 0 && $min1 == 0;
$max_match = $time2 == '00:00:00' || $hour2 == 23 && $min2 == $max_minutes || $hour1 == 0 && $hour2 == 0 && $min1 == 0 && $min2 == 0;
break;
case 'hour':
$min_match = $time1 == '00:00:00' || $hour1 == 0;
$max_match = $time2 == '00:00:00' || $hour2 == 23 || $hour1 == 0 && $hour2 == 0;
break;
default:
$min_match = TRUE;
$max_match = FALSE;
}
if ($min_match && $max_match) {
return TRUE;
}
return FALSE;
}
function &date_get_nested_elements(&$form, $field_name) {
$elements = array();
foreach (element_children($form) as $key) {
if ($key === $field_name) {
$elements[] =& $form[$key];
}
else {
if (is_array($form[$key])) {
$nested_form =& $form[$key];
if ($sub_elements =& date_get_nested_elements($nested_form, $field_name)) {
$elements = array_merge($elements, $sub_elements);
}
}
}
}
return $elements;
}