/** * Calculates the date or object * * @param string $calc Calculation to make, one of: 'add'|'sub'|'cmp'|'copy'|'set' * @param string|integer|array|Zend_Date $date Date or datepart to calculate with * @param string $part Part of the date to calculate, if null the timestamp is used * @param string|Zend_Locale $locale Locale for parsing input * @return integer|string|Zend_Date new timestamp * @throws Zend_Date_Exception */ private function _calculate($calc, $date, $part, $locale) { if ($date === null) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception('parameter $date must be set, null is not allowed'); } if ($part !== null && strlen($part) !== 2 && Zend_Locale::isLocale($part, null, false)) { $locale = $part; $part = null; } if ($locale === null) { $locale = $this->getLocale(); } $locale = (string) $locale; // Create date parts $year = $this->toString(self::YEAR, 'iso'); $month = $this->toString(self::MONTH_SHORT, 'iso'); $day = $this->toString(self::DAY_SHORT, 'iso'); $hour = $this->toString(self::HOUR_SHORT, 'iso'); $minute = $this->toString(self::MINUTE_SHORT, 'iso'); $second = $this->toString(self::SECOND_SHORT, 'iso'); // If object extract value if ($date instanceof Zend_Date) { $date = $date->toString($part, 'iso', $locale); } if (is_array($date) === true) { if (empty($part) === false) { switch ($part) { // Fall through case self::DAY: case self::DAY_SHORT: if (isset($date['day']) === true) { $date = $date['day']; } break; // Fall through // Fall through case self::WEEKDAY_SHORT: case self::WEEKDAY: case self::WEEKDAY_8601: case self::WEEKDAY_DIGIT: case self::WEEKDAY_NARROW: case self::WEEKDAY_NAME: if (isset($date['weekday']) === true) { $date = $date['weekday']; $part = self::WEEKDAY_DIGIT; } break; case self::DAY_OF_YEAR: if (isset($date['day_of_year']) === true) { $date = $date['day_of_year']; } break; // Fall through // Fall through case self::MONTH: case self::MONTH_SHORT: case self::MONTH_NAME: case self::MONTH_NAME_SHORT: case self::MONTH_NAME_NARROW: if (isset($date['month']) === true) { $date = $date['month']; } break; // Fall through // Fall through case self::YEAR: case self::YEAR_SHORT: case self::YEAR_8601: case self::YEAR_SHORT_8601: if (isset($date['year']) === true) { $date = $date['year']; } break; // Fall through // Fall through case self::HOUR: case self::HOUR_AM: case self::HOUR_SHORT: case self::HOUR_SHORT_AM: if (isset($date['hour']) === true) { $date = $date['hour']; } break; // Fall through // Fall through case self::MINUTE: case self::MINUTE_SHORT: if (isset($date['minute']) === true) { $date = $date['minute']; } break; // Fall through // Fall through case self::SECOND: case self::SECOND_SHORT: if (isset($date['second']) === true) { $date = $date['second']; } break; // Fall through // Fall through case self::TIMEZONE: case self::TIMEZONE_NAME: if (isset($date['timezone']) === true) { $date = $date['timezone']; } break; case self::TIMESTAMP: if (isset($date['timestamp']) === true) { $date = $date['timestamp']; } break; case self::WEEK: if (isset($date['week']) === true) { $date = $date['week']; } break; case self::TIMEZONE_SECS: if (isset($date['gmtsecs']) === true) { $date = $date['gmtsecs']; } break; default: require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("datepart for part ({$part}) not found in array"); break; } } else { $hours = 0; if (isset($date['hour']) === true) { $hours = $date['hour']; } $minutes = 0; if (isset($date['minute']) === true) { $minutes = $date['minute']; } $seconds = 0; if (isset($date['second']) === true) { $seconds = $date['second']; } $months = 0; if (isset($date['month']) === true) { $months = $date['month']; } $days = 0; if (isset($date['day']) === true) { $days = $date['day']; } $years = 0; if (isset($date['year']) === true) { $years = $date['year']; } return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, $months, $days, $years, true), $this->mktime($hour, $minute, $second, $month, $day, $year, true), $hour); } } // $date as object, part of foreign date as own date switch ($part) { // day formats case self::DAY: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true), $this->mktime(0, 0, 0, 1, 1 + intval($day), 1970, true), $hour); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, day expected", 0, null, $date); break; case self::WEEKDAY_SHORT: $daylist = Zend_Locale_Data::getList($locale, 'day'); $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); $cnt = 0; foreach ($daylist as $key => $value) { if (strtoupper(iconv_substr($value, 0, 3, 'UTF-8')) == strtoupper($date)) { $found = $cnt; break; } ++$cnt; } // Weekday found if ($cnt < 7) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); } // Weekday not found require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, weekday expected", 0, null, $date); break; case self::DAY_SHORT: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true), $this->mktime(0, 0, 0, 1, 1 + intval($day), 1970, true), $hour); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, day expected", 0, null, $date); break; case self::WEEKDAY: $daylist = Zend_Locale_Data::getList($locale, 'day'); $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); $cnt = 0; foreach ($daylist as $key => $value) { if (strtoupper($value) == strtoupper($date)) { $found = $cnt; break; } ++$cnt; } // Weekday found if ($cnt < 7) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); } // Weekday not found require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, weekday expected", 0, null, $date); break; case self::WEEKDAY_8601: $weekday = (int) $this->toString(self::WEEKDAY_8601, 'iso', $locale); if (intval($date) > 0 and intval($date) < 8) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true), $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); } // Weekday not found require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, weekday expected", 0, null, $date); break; case self::DAY_SUFFIX: require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception('day suffix not supported', 0, null, $date); break; case self::WEEKDAY_DIGIT: $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); if (is_numeric($date) and intval($date) >= 0 and intval($date) < 7) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $date, 1970, true), $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); } // Weekday not found require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, weekday expected", 0, null, $date); break; case self::DAY_OF_YEAR: if (is_numeric($date)) { if ($calc == 'add' || $calc == 'sub') { $year = 1970; ++$date; ++$day; } return $this->_assign($calc, $this->mktime(0, 0, 0, 1, $date, $year, true), $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, day expected", 0, null, $date); break; case self::WEEKDAY_NARROW: $daylist = Zend_Locale_Data::getList($locale, 'day', array('gregorian', 'format', 'abbreviated')); $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); $cnt = 0; foreach ($daylist as $key => $value) { if (strtoupper(iconv_substr($value, 0, 1, 'UTF-8')) == strtoupper($date)) { $found = $cnt; break; } ++$cnt; } // Weekday found if ($cnt < 7) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); } // Weekday not found require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, weekday expected", 0, null, $date); break; case self::WEEKDAY_NAME: $daylist = Zend_Locale_Data::getList($locale, 'day', array('gregorian', 'format', 'abbreviated')); $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); $cnt = 0; foreach ($daylist as $key => $value) { if (strtoupper($value) == strtoupper($date)) { $found = $cnt; break; } ++$cnt; } // Weekday found if ($cnt < 7) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); } // Weekday not found require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, weekday expected", 0, null, $date); break; // week formats // week formats case self::WEEK: if (is_numeric($date)) { $week = (int) $this->toString(self::WEEK, 'iso', $locale); return $this->_assign($calc, parent::mktime(0, 0, 0, 1, 1 + $date * 7, 1970, true), parent::mktime(0, 0, 0, 1, 1 + $week * 7, 1970, true), $hour); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, week expected", 0, null, $date); break; // month formats // month formats case self::MONTH_NAME: $monthlist = Zend_Locale_Data::getList($locale, 'month'); $cnt = 0; foreach ($monthlist as $key => $value) { if (strtoupper($value) == strtoupper($date)) { $found = $key; break; } ++$cnt; } $date = array_search($date, $monthlist); // Monthname found if ($cnt < 12) { $fixday = 0; if ($calc == 'add') { $date += $found; $calc = 'set'; if (self::$_options['extend_month'] == false) { $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday = $parts['mday'] < $day ? -$parts['mday'] : $parts['mday'] - $day; } } } else { if ($calc == 'sub') { $date = $month - $found; $calc = 'set'; if (self::$_options['extend_month'] == false) { $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday = $parts['mday'] < $day ? -$parts['mday'] : $parts['mday'] - $day; } } } } return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); } // Monthname not found require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, month expected", 0, null, $date); break; case self::MONTH: if (is_numeric($date)) { $fixday = 0; if ($calc == 'add') { $date += $month; $calc = 'set'; if (self::$_options['extend_month'] == false) { $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday = $parts['mday'] < $day ? -$parts['mday'] : $parts['mday'] - $day; } } } else { if ($calc == 'sub') { $date = $month - $date; $calc = 'set'; if (self::$_options['extend_month'] == false) { $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday = $parts['mday'] < $day ? -$parts['mday'] : $parts['mday'] - $day; } } } } return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, month expected", 0, null, $date); break; case self::MONTH_NAME_SHORT: $monthlist = Zend_Locale_Data::getList($locale, 'month', array('gregorian', 'format', 'abbreviated')); $cnt = 0; foreach ($monthlist as $key => $value) { if (strtoupper($value) == strtoupper($date)) { $found = $key; break; } ++$cnt; } $date = array_search($date, $monthlist); // Monthname found if ($cnt < 12) { $fixday = 0; if ($calc == 'add') { $date += $found; $calc = 'set'; if (self::$_options['extend_month'] === false) { $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday = $parts['mday'] < $day ? -$parts['mday'] : $parts['mday'] - $day; } } } else { if ($calc == 'sub') { $date = $month - $found; $calc = 'set'; if (self::$_options['extend_month'] === false) { $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday = $parts['mday'] < $day ? -$parts['mday'] : $parts['mday'] - $day; } } } } return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); } // Monthname not found require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, month expected", 0, null, $date); break; case self::MONTH_SHORT: if (is_numeric($date) === true) { $fixday = 0; if ($calc === 'add') { $date += $month; $calc = 'set'; if (self::$_options['extend_month'] === false) { $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday = $parts['mday'] < $day ? -$parts['mday'] : $parts['mday'] - $day; } } } else { if ($calc === 'sub') { $date = $month - $date; $calc = 'set'; if (self::$_options['extend_month'] === false) { $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday = $parts['mday'] < $day ? -$parts['mday'] : $parts['mday'] - $day; } } } } return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, month expected", 0, null, $date); break; case self::MONTH_DAYS: require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception('month days not supported', 0, null, $date); break; case self::MONTH_NAME_NARROW: $monthlist = Zend_Locale_Data::getList($locale, 'month', array('gregorian', 'stand-alone', 'narrow')); $cnt = 0; foreach ($monthlist as $key => $value) { if (strtoupper($value) === strtoupper($date)) { $found = $key; break; } ++$cnt; } $date = array_search($date, $monthlist); // Monthname found if ($cnt < 12) { $fixday = 0; if ($calc === 'add') { $date += $found; $calc = 'set'; if (self::$_options['extend_month'] === false) { $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday = $parts['mday'] < $day ? -$parts['mday'] : $parts['mday'] - $day; } } } else { if ($calc === 'sub') { $date = $month - $found; $calc = 'set'; if (self::$_options['extend_month'] === false) { $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday = $parts['mday'] < $day ? -$parts['mday'] : $parts['mday'] - $day; } } } } return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); } // Monthname not found require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, month expected", 0, null, $date); break; // year formats // year formats case self::LEAPYEAR: require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception('leap year not supported', 0, null, $date); break; case self::YEAR_8601: if (is_numeric($date)) { if ($calc === 'add') { $date += $year; $calc = 'set'; } else { if ($calc === 'sub') { $date = $year - $date; $calc = 'set'; } } return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, intval($date), true), $this->mktime(0, 0, 0, $month, $day, $year, true), false); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, year expected", 0, null, $date); break; case self::YEAR: if (is_numeric($date)) { if ($calc === 'add') { $date += $year; $calc = 'set'; } else { if ($calc === 'sub') { $date = $year - $date; $calc = 'set'; } } return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, intval($date), true), $this->mktime(0, 0, 0, $month, $day, $year, true), false); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, year expected", 0, null, $date); break; case self::YEAR_SHORT: if (is_numeric($date)) { $date = intval($date); if ($calc == 'set' || $calc == 'cmp') { $date = self::getFullYear($date); } if ($calc === 'add') { $date += $year; $calc = 'set'; } else { if ($calc === 'sub') { $date = $year - $date; $calc = 'set'; } } return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, $date, true), $this->mktime(0, 0, 0, $month, $day, $year, true), false); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, year expected", 0, null, $date); break; case self::YEAR_SHORT_8601: if (is_numeric($date)) { $date = intval($date); if ($calc === 'set' || $calc === 'cmp') { $date = self::getFullYear($date); } if ($calc === 'add') { $date += $year; $calc = 'set'; } else { if ($calc === 'sub') { $date = $year - $date; $calc = 'set'; } } return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, $date, true), $this->mktime(0, 0, 0, $month, $day, $year, true), false); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, year expected", 0, null, $date); break; // time formats // time formats case self::MERIDIEM: require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception('meridiem not supported', 0, null, $date); break; case self::SWATCH: if (is_numeric($date)) { $rest = intval($date); $hours = floor($rest * 24 / 1000); $rest = $rest - $hours * 1000 / 24; $minutes = floor($rest * 1440 / 1000); $rest = $rest - $minutes * 1000 / 1440; $seconds = floor($rest * 86400 / 1000); return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, 1, 1, 1970, true), $this->mktime($hour, $minute, $second, 1, 1, 1970, true), false); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, swatchstamp expected", 0, null, $date); break; case self::HOUR_SHORT_AM: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, hour expected", 0, null, $date); break; case self::HOUR_SHORT: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, hour expected", 0, null, $date); break; case self::HOUR_AM: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, hour expected", 0, null, $date); break; case self::HOUR: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, hour expected", 0, null, $date); break; case self::MINUTE: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(0, intval($date), 0, 1, 1, 1970, true), $this->mktime(0, $minute, 0, 1, 1, 1970, true), false); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, minute expected", 0, null, $date); break; case self::SECOND: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(0, 0, intval($date), 1, 1, 1970, true), $this->mktime(0, 0, $second, 1, 1, 1970, true), false); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, second expected", 0, null, $date); break; case self::MILLISECOND: if (is_numeric($date)) { switch ($calc) { case 'set': return $this->setMillisecond($date); break; case 'add': return $this->addMillisecond($date); break; case 'sub': return $this->subMillisecond($date); break; } return $this->compareMillisecond($date); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, milliseconds expected", 0, null, $date); break; case self::MINUTE_SHORT: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(0, intval($date), 0, 1, 1, 1970, true), $this->mktime(0, $minute, 0, 1, 1, 1970, true), false); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, minute expected", 0, null, $date); break; case self::SECOND_SHORT: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(0, 0, intval($date), 1, 1, 1970, true), $this->mktime(0, 0, $second, 1, 1, 1970, true), false); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, second expected", 0, null, $date); break; // timezone formats // break intentionally omitted // timezone formats // break intentionally omitted case self::TIMEZONE_NAME: case self::TIMEZONE: case self::TIMEZONE_SECS: require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception('timezone not supported', 0, null, $date); break; case self::DAYLIGHT: require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception('daylight not supported', 0, null, $date); break; case self::GMT_DIFF: case self::GMT_DIFF_SEP: require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception('gmtdiff not supported', 0, null, $date); break; // date strings // date strings case self::ISO_8601: // (-)YYYY-MM-dd preg_match('/^(-{0,1}\\d{4})-(\\d{2})-(\\d{2})/', $date, $datematch); // (-)YY-MM-dd if (empty($datematch)) { preg_match('/^(-{0,1}\\d{2})-(\\d{2})-(\\d{2})/', $date, $datematch); } // (-)YYYYMMdd if (empty($datematch)) { preg_match('/^(-{0,1}\\d{4})(\\d{2})(\\d{2})/', $date, $datematch); } // (-)YYMMdd if (empty($datematch)) { preg_match('/^(-{0,1}\\d{2})(\\d{2})(\\d{2})/', $date, $datematch); } $tmpdate = $date; if (!empty($datematch)) { $dateMatchCharCount = iconv_strlen($datematch[0], 'UTF-8'); $tmpdate = iconv_substr($date, $dateMatchCharCount, iconv_strlen($date, 'UTF-8') - $dateMatchCharCount, 'UTF-8'); } // (T)hh:mm:ss preg_match('/[T,\\s]{0,1}(\\d{2}):(\\d{2}):(\\d{2})/', $tmpdate, $timematch); if (empty($timematch)) { preg_match('/[T,\\s]{0,1}(\\d{2})(\\d{2})(\\d{2})/', $tmpdate, $timematch); } if (empty($datematch) and empty($timematch)) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("unsupported ISO8601 format ({$date})", 0, null, $date); } if (!empty($timematch)) { $timeMatchCharCount = iconv_strlen($timematch[0], 'UTF-8'); $tmpdate = iconv_substr($tmpdate, $timeMatchCharCount, iconv_strlen($tmpdate, 'UTF-8') - $timeMatchCharCount, 'UTF-8'); } if (empty($datematch)) { $datematch[1] = 1970; $datematch[2] = 1; $datematch[3] = 1; } else { if (iconv_strlen($datematch[1], 'UTF-8') == 2) { $datematch[1] = self::getFullYear($datematch[1]); } } if (empty($timematch)) { $timematch[1] = 0; $timematch[2] = 0; $timematch[3] = 0; } if ($calc == 'set' || $calc == 'cmp') { --$datematch[2]; --$month; --$datematch[3]; --$day; $datematch[1] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($timematch[1], $timematch[2], $timematch[3], 1 + $datematch[2], 1 + $datematch[3], 1970 + $datematch[1], false), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, false), false); break; case self::RFC_2822: $result = preg_match('/^\\w{3},\\s(\\d{1,2})\\s(\\w{3})\\s(\\d{4})\\s' . '(\\d{2}):(\\d{2}):{0,1}(\\d{0,2})\\s([+-]' . '{1}\\d{4}|\\w{1,20})$/', $date, $match); if (!$result) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("no RFC 2822 format ({$date})", 0, null, $date); } $months = $this->_getDigitFromName($match[2]); if ($calc == 'set' || $calc == 'cmp') { --$months; --$month; --$match[1]; --$day; $match[3] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], false), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, false), false); break; case self::TIMESTAMP: if (is_numeric($date)) { return $this->_assign($calc, $date, $this->getUnixTimestamp()); } require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, timestamp expected", 0, null, $date); break; // additional formats // break intentionally omitted // additional formats // break intentionally omitted case self::ERA: case self::ERA_NAME: require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception('era not supported', 0, null, $date); break; case self::DATES: try { $parsed = Zend_Locale_Format::getDate($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true)); if ($calc == 'set' || $calc == 'cmp') { --$parsed['month']; --$month; --$parsed['day']; --$day; $parsed['year'] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); } catch (Zend_Locale_Exception $e) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); } break; case self::DATE_FULL: try { $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'full')); $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); if ($calc == 'set' || $calc == 'cmp') { --$parsed['month']; --$month; --$parsed['day']; --$day; $parsed['year'] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); } catch (Zend_Locale_Exception $e) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); } break; case self::DATE_LONG: try { $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'long')); $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); if ($calc == 'set' || $calc == 'cmp') { --$parsed['month']; --$month; --$parsed['day']; --$day; $parsed['year'] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); } catch (Zend_Locale_Exception $e) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); } break; case self::DATE_MEDIUM: try { $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'medium')); $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); if ($calc == 'set' || $calc == 'cmp') { --$parsed['month']; --$month; --$parsed['day']; --$day; $parsed['year'] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); } catch (Zend_Locale_Exception $e) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); } break; case self::DATE_SHORT: try { $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'short')); $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); $parsed['year'] = self::getFullYear($parsed['year']); if ($calc == 'set' || $calc == 'cmp') { --$parsed['month']; --$month; --$parsed['day']; --$day; $parsed['year'] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); } catch (Zend_Locale_Exception $e) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); } break; case self::TIMES: try { if ($calc != 'set') { $month = 1; $day = 1; $year = 1970; } $parsed = Zend_Locale_Format::getTime($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true)); return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); } catch (Zend_Locale_Exception $e) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); } break; case self::TIME_FULL: try { $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'full')); $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); if ($calc != 'set') { $month = 1; $day = 1; $year = 1970; } if (!isset($parsed['second'])) { $parsed['second'] = 0; } return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); } catch (Zend_Locale_Exception $e) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); } break; case self::TIME_LONG: try { $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'long')); $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); if ($calc != 'set') { $month = 1; $day = 1; $year = 1970; } return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); } catch (Zend_Locale_Exception $e) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); } break; case self::TIME_MEDIUM: try { $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'medium')); $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); if ($calc != 'set') { $month = 1; $day = 1; $year = 1970; } return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); } catch (Zend_Locale_Exception $e) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); } break; case self::TIME_SHORT: try { $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'short')); $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); if ($calc != 'set') { $month = 1; $day = 1; $year = 1970; } if (!isset($parsed['second'])) { $parsed['second'] = 0; } return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); } catch (Zend_Locale_Exception $e) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); } break; case self::DATETIME: try { $parsed = Zend_Locale_Format::getDateTime($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true)); if ($calc == 'set' || $calc == 'cmp') { --$parsed['month']; --$month; --$parsed['day']; --$day; $parsed['year'] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); } catch (Zend_Locale_Exception $e) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); } break; case self::DATETIME_FULL: try { $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'full')); $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); if ($calc == 'set' || $calc == 'cmp') { --$parsed['month']; --$month; --$parsed['day']; --$day; $parsed['year'] -= 1970; $year -= 1970; } if (!isset($parsed['second'])) { $parsed['second'] = 0; } return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); } catch (Zend_Locale_Exception $e) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); } break; case self::DATETIME_LONG: try { $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'long')); $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); if ($calc == 'set' || $calc == 'cmp') { --$parsed['month']; --$month; --$parsed['day']; --$day; $parsed['year'] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); } catch (Zend_Locale_Exception $e) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); } break; case self::DATETIME_MEDIUM: try { $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'medium')); $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); if ($calc == 'set' || $calc == 'cmp') { --$parsed['month']; --$month; --$parsed['day']; --$day; $parsed['year'] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); } catch (Zend_Locale_Exception $e) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); } break; case self::DATETIME_SHORT: try { $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'short')); $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); $parsed['year'] = self::getFullYear($parsed['year']); if ($calc == 'set' || $calc == 'cmp') { --$parsed['month']; --$month; --$parsed['day']; --$day; $parsed['year'] -= 1970; $year -= 1970; } if (!isset($parsed['second'])) { $parsed['second'] = 0; } return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); } catch (Zend_Locale_Exception $e) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); } break; // ATOM and RFC_3339 are identical // ATOM and RFC_3339 are identical case self::ATOM: case self::RFC_3339: $result = preg_match('/^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})\\d{0,4}([+-]{1}\\d{2}:\\d{2}|Z)$/', $date, $match); if (!$result) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, ATOM format expected", 0, null, $date); } if ($calc == 'set' || $calc == 'cmp') { --$match[2]; --$month; --$match[3]; --$day; $match[1] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $match[2], 1 + $match[3], 1970 + $match[1], true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); break; case self::COOKIE: $result = preg_match("/^\\w{6,9},\\s(\\d{2})-(\\w{3})-(\\d{2})\\s(\\d{2}):(\\d{2}):(\\d{2})\\s.{3,20}\$/", $date, $match); if (!$result) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, COOKIE format expected", 0, null, $date); } $matchStartPos = iconv_strpos($match[0], ' ', 0, 'UTF-8') + 1; $match[0] = iconv_substr($match[0], $matchStartPos, iconv_strlen($match[0], 'UTF-8') - $matchStartPos, 'UTF-8'); $months = $this->_getDigitFromName($match[2]); $match[3] = self::getFullYear($match[3]); if ($calc == 'set' || $calc == 'cmp') { --$months; --$month; --$match[1]; --$day; $match[3] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); break; case self::RFC_822: case self::RFC_1036: // new RFC 822 format, identical to RFC 1036 standard $result = preg_match('/^\\w{0,3},{0,1}\\s{0,1}(\\d{1,2})\\s(\\w{3})\\s(\\d{2})\\s(\\d{2}):(\\d{2}):{0,1}(\\d{0,2})\\s([+-]{1}\\d{4}|\\w{1,20})$/', $date, $match); if (!$result) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, RFC 822 date format expected", 0, null, $date); } $months = $this->_getDigitFromName($match[2]); $match[3] = self::getFullYear($match[3]); if ($calc == 'set' || $calc == 'cmp') { --$months; --$month; --$match[1]; --$day; $match[3] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], false), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, false), false); break; case self::RFC_850: $result = preg_match('/^\\w{6,9},\\s(\\d{2})-(\\w{3})-(\\d{2})\\s(\\d{2}):(\\d{2}):(\\d{2})\\s.{3,21}$/', $date, $match); if (!$result) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, RFC 850 date format expected", 0, null, $date); } $months = $this->_getDigitFromName($match[2]); $match[3] = self::getFullYear($match[3]); if ($calc == 'set' || $calc == 'cmp') { --$months; --$month; --$match[1]; --$day; $match[3] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); break; case self::RFC_1123: $result = preg_match('/^\\w{0,3},{0,1}\\s{0,1}(\\d{1,2})\\s(\\w{3})\\s(\\d{2,4})\\s(\\d{2}):(\\d{2}):{0,1}(\\d{0,2})\\s([+-]{1}\\d{4}|\\w{1,20})$/', $date, $match); if (!$result) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, RFC 1123 date format expected", 0, null, $date); } $months = $this->_getDigitFromName($match[2]); if ($calc == 'set' || $calc == 'cmp') { --$months; --$month; --$match[1]; --$day; $match[3] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); break; case self::RSS: $result = preg_match('/^\\w{3},\\s(\\d{2})\\s(\\w{3})\\s(\\d{2,4})\\s(\\d{1,2}):(\\d{2}):(\\d{2})\\s.{1,21}$/', $date, $match); if (!$result) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, RSS date format expected", 0, null, $date); } $months = $this->_getDigitFromName($match[2]); $match[3] = self::getFullYear($match[3]); if ($calc == 'set' || $calc == 'cmp') { --$months; --$month; --$match[1]; --$day; $match[3] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); break; case self::W3C: $result = preg_match('/^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})[+-]{1}\\d{2}:\\d{2}$/', $date, $match); if (!$result) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception("invalid date ({$date}) operand, W3C date format expected", 0, null, $date); } if ($calc == 'set' || $calc == 'cmp') { --$match[2]; --$month; --$match[3]; --$day; $match[1] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $match[2], 1 + $match[3], 1970 + $match[1], true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); break; default: if (!is_numeric($date) || !empty($part)) { try { if (empty($part)) { $part = Zend_Locale_Format::getDateFormat($locale) . " "; $part .= Zend_Locale_Format::getTimeFormat($locale); } $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $part, 'locale' => $locale, 'fix_date' => true, 'format_type' => 'iso')); if (strpos(strtoupper($part), 'YY') !== false and strpos(strtoupper($part), 'YYYY') === false) { $parsed['year'] = self::getFullYear($parsed['year']); } if ($calc == 'set' || $calc == 'cmp') { if (isset($parsed['month'])) { --$parsed['month']; } else { $parsed['month'] = 0; } if (isset($parsed['day'])) { --$parsed['day']; } else { $parsed['day'] = 0; } if (!isset($parsed['year'])) { $parsed['year'] = 1970; } } return $this->_assign($calc, $this->mktime(isset($parsed['hour']) ? $parsed['hour'] : 0, isset($parsed['minute']) ? $parsed['minute'] : 0, isset($parsed['second']) ? $parsed['second'] : 0, isset($parsed['month']) ? 1 + $parsed['month'] : 1, isset($parsed['day']) ? 1 + $parsed['day'] : 1, $parsed['year'], false), $this->getUnixTimestamp(), false); } catch (Zend_Locale_Exception $e) { if (!is_numeric($date)) { require_once 'Zend/Date/Exception.php'; throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); } } } return $this->_assign($calc, $date, $this->getUnixTimestamp(), false); break; } }
/** * Get unix timestamp. * Added limitation: $year value must be between -10 000 and 10 000 * Parent method implementation causes 504 error if it gets too big(small) year value * * @see Zend_Date_DateObject::mktime * @throws Zend_Date_Exception * @param $hour * @param $minute * @param $second * @param $month * @param $day * @param $year * @param bool $gmt * @return float|int */ protected function mktime($hour, $minute, $second, $month, $day, $year, $gmt = false) { $day = intval($day); $month = intval($month); $year = intval($year); // correct months > 12 and months < 1 if ($month > 12) { $overlap = floor($month / 12); $year += $overlap; $month -= $overlap * 12; } else { $overlap = ceil((1 - $month) / 12); $year -= $overlap; $month += $overlap * 12; } if ($year > self::YEAR_MAX_VALUE || $year < self::YEAR_MIN_VALUE) { throw new Zend_Date_Exception('Invalid year, it must be between ' . self::YEAR_MIN_VALUE . ' and ' . self::YEAR_MAX_VALUE); } return parent::mktime($hour, $minute, $second, $month, $day, $year, $gmt); }
/** * Calculates the date or object * * @param string $calc Calculation to make, one of: 'add'|'sub'|'cmp'|'copy'|'set' * @param string|integer|array|Zend_Date $date Date or datepart to calculate with * @param string $part Part of the date to calculate, if null the timestamp is used * @param string|Zend_Locale $locale Locale for parsing input * @return integer|string|Zend_Date new timestamp * @throws Zend_Date_Exception */ private function _calculate($calc, $date, $part, $locale) { if (is_null($date)) { throw new Zend_Date_Exception('parameter $date must be set, null is not allowed'); } if (Zend_Locale::isLocale($part)) { $locale = $part; $part = null; } if ($locale === null) { $locale = $this->getLocale(); } if ($locale instanceof Zend_Locale) { $locale = $locale->toString(); } // create date parts $year = $this->get(Zend_Date::YEAR); $month = $this->get(Zend_Date::MONTH_SHORT); $day = $this->get(Zend_Date::DAY_SHORT); $hour = $this->get(Zend_Date::HOUR_SHORT); $minute = $this->get(Zend_Date::MINUTE_SHORT); $second = $this->get(Zend_Date::SECOND_SHORT); // if object extract value if ($date instanceof Zend_Date) { $date = $date->get($part, $locale); } if (is_array($date)) { if (!empty($part)) { switch ($part) { // Fall through case Zend_Date::DAY: case Zend_Date::DAY_SHORT: if (array_key_exists('day', $date)) { $date = $date['day']; } break; // Fall through // Fall through case Zend_Date::WEEKDAY_SHORT: case Zend_Date::WEEKDAY: case Zend_Date::WEEKDAY_8601: case Zend_Date::WEEKDAY_DIGIT: case Zend_Date::WEEKDAY_NARROW: case Zend_Date::WEEKDAY_NAME: if (array_key_exists('weekday', $date)) { $date = $date['weekday']; $part = Zend_Date::WEEKDAY_DIGIT; } break; case Zend_Date::DAY_OF_YEAR: if (array_key_exists('day_of_year', $date)) { $date = $date['day_of_year']; } break; // Fall through // Fall through case Zend_Date::MONTH: case Zend_Date::MONTH_SHORT: case Zend_Date::MONTH_NAME: case Zend_Date::MONTH_NAME_SHORT: case Zend_Date::MONTH_NAME_NARROW: if (array_key_exists('month', $date)) { $date = $date['month']; } break; // Fall through // Fall through case Zend_Date::YEAR: case Zend_Date::YEAR_SHORT: case Zend_Date::YEAR_8601: case Zend_Date::YEAR_SHORT_8601: if (array_key_exists('year', $date)) { $date = $date['year']; } break; // Fall through // Fall through case Zend_Date::HOUR: case Zend_Date::HOUR_AM: case Zend_Date::HOUR_SHORT: case Zend_Date::HOUR_SHORT_AM: if (array_key_exists('hour', $date)) { $date = $date['hour']; } break; // Fall through // Fall through case Zend_Date::MINUTE: case Zend_Date::MINUTE_SHORT: if (array_key_exists('minute', $date)) { $date = $date['minute']; } break; // Fall through // Fall through case Zend_Date::SECOND: case Zend_Date::SECOND_SHORT: if (array_key_exists('second', $date)) { $date = $date['second']; } break; // Fall through // Fall through case Zend_Date::TIMEZONE: case Zend_Date::TIMEZONE_NAME: if (array_key_exists('timezone', $date)) { $date = $date['timezone']; } break; case Zend_Date::TIMESTAMP: if (array_key_exists('timestamp', $date)) { $date = $date['timestamp']; } break; case Zend_Date::WEEK: if (array_key_exists('week', $date)) { $date = $date['week']; } break; case Zend_Date::TIMEZONE_SECS: if (array_key_exists('gmtsecs', $date)) { $date = $date['gmtsecs']; } break; default: throw new Zend_Date_Exception("datepart for part ({$part}) not found in array"); break; } } else { $hours = 0; if (array_key_exists("hour", $date)) { $hours = $date['hour']; } $minutes = 0; if (array_key_exists('minute', $date)) { $minutes = $date['minute']; } $seconds = 0; if (array_key_exists('second', $date)) { $seconds = $date['second']; } $months = 0; if (array_key_exists('month', $date)) { $months = $date['month']; } $days = 0; if (array_key_exists('day', $date)) { $days = $date['day']; } $years = 0; if (array_key_exists('year', $date)) { $years = $date['year']; } return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, $months, $days, $years, true), $this->mktime($hour, $minute, $second, $month, $day, $year, true), $hour); } } // $date as object, part of foreign date as own date switch ($part) { // day formats case Zend_Date::DAY: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true), $this->mktime(0, 0, 0, 1, 1 + intval($day), 1970, true), $hour); } throw new Zend_Date_Exception("invalid date ({$date}) operand, day expected", $date); break; case Zend_Date::WEEKDAY_SHORT: $daylist = Zend_Locale_Data::getContent($locale, 'daylist', array('gregorian', 'format', 'wide')); $weekday = (int) $this->get(Zend_Date::WEEKDAY_DIGIT, $locale); $cnt = 0; foreach ($daylist as $key => $value) { if (strtoupper(substr($value, 0, 3)) == strtoupper($date)) { $found = $cnt; break; } ++$cnt; } // Weekday found if ($cnt < 7) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); } // Weekday not found throw new Zend_Date_Exception("invalid date ({$date}) operand, weekday expected", $date); break; case Zend_Date::DAY_SHORT: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true), $this->mktime(0, 0, 0, 1, 1 + intval($day), 1970, true), $hour); } throw new Zend_Date_Exception("invalid date ({$date}) operand, day expected", $date); break; case Zend_Date::WEEKDAY: $daylist = Zend_Locale_Data::getContent($locale, 'daylist', array('gregorian', 'format', 'wide')); $weekday = (int) $this->get(Zend_Date::WEEKDAY_DIGIT, $locale); $cnt = 0; foreach ($daylist as $key => $value) { if (strtoupper($value) == strtoupper($date)) { $found = $cnt; break; } ++$cnt; } // Weekday found if ($cnt < 7) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); } // Weekday not found throw new Zend_Date_Exception("invalid date ({$date}) operand, weekday expected", $date); break; case Zend_Date::WEEKDAY_8601: $weekday = (int) $this->get(Zend_Date::WEEKDAY_8601, $locale); if (intval($date) > 0 and intval($date) < 8) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true), $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); } // Weekday not found throw new Zend_Date_Exception("invalid date ({$date}) operand, weekday expected", $date); break; case Zend_Date::DAY_SUFFIX: throw new Zend_Date_Exception('day suffix not supported', $date); break; case Zend_Date::WEEKDAY_DIGIT: $weekday = (int) $this->get(Zend_Date::WEEKDAY_DIGIT, $locale); if (is_numeric($date) and intval($date) >= 0 and intval($date) < 7) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $date, 1970, true), $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); } // Weekday not found throw new Zend_Date_Exception("invalid date ({$date}) operand, weekday expected", $date); break; case Zend_Date::DAY_OF_YEAR: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $date, 1970, true), $this->mktime(0, 0, 0, $month, 1 + $day, 1970, true), $hour); } throw new Zend_Date_Exception("invalid date ({$date}) operand, day expected", $date); break; case Zend_Date::WEEKDAY_NARROW: $daylist = Zend_Locale_Data::getContent($locale, 'daylist', array('gregorian', 'format', 'abbreviated')); $weekday = (int) $this->get(Zend_Date::WEEKDAY_DIGIT, $locale); $cnt = 0; foreach ($daylist as $key => $value) { if (strtoupper(substr($value, 0, 1)) == strtoupper($date)) { $found = $cnt; break; } ++$cnt; } // Weekday found if ($cnt < 7) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); } // Weekday not found throw new Zend_Date_Exception("invalid date ({$date}) operand, weekday expected", $date); break; case Zend_Date::WEEKDAY_NAME: $daylist = Zend_Locale_Data::getContent($locale, 'daylist', array('gregorian', 'format', 'abbreviated')); $weekday = (int) $this->get(Zend_Date::WEEKDAY_DIGIT, $locale); $cnt = 0; foreach ($daylist as $key => $value) { if (strtoupper($value) == strtoupper($date)) { $found = $cnt; break; } ++$cnt; } // Weekday found if ($cnt < 7) { return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); } // Weekday not found throw new Zend_Date_Exception("invalid date ({$date}) operand, weekday expected", $date); break; // week formats // week formats case Zend_Date::WEEK: if (is_numeric($date)) { $week = (int) $this->get(Zend_Date::WEEK, $locale); return $this->_assign($calc, parent::mktime(0, 0, 0, 1, 1 + $date * 7, 1970, true), parent::mktime(0, 0, 0, 1, 1 + $week * 7, 1970, true), $hour); } throw new Zend_Date_Exception("invalid date ({$date}) operand, week expected", $date); break; // month formats // month formats case Zend_Date::MONTH_NAME: $monthlist = Zend_Locale_Data::getContent($locale, 'monthlist', array('gregorian', 'format', 'wide')); $cnt = 0; foreach ($monthlist as $key => $value) { if (strtoupper($value) == strtoupper($date)) { $found = $key; break; } ++$cnt; } $date = array_search($date, $monthlist); // Monthname found if ($cnt < 12) { $fixday = 0; if ($calc == 'add') { $date += $found; $calc = 'set'; if (self::$_Options['extend_month'] == false) { $parts = $this->getDateParts($this->mktime(0, 0, 0, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday -= $parts['mday']; } } } else { if ($calc == 'sub') { $date = $month - $found; $calc = 'set'; if (self::$_Options['extend_month'] == false) { $parts = $this->getDateParts($this->mktime(0, 0, 0, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday -= $parts['mday']; } } } } return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); } // Monthname not found throw new Zend_Date_Exception("invalid date ({$date}) operand, month expected", $date); break; case Zend_Date::MONTH: if (is_numeric($date)) { $fixday = 0; if ($calc == 'add') { $date += $month; $calc = 'set'; if (self::$_Options['extend_month'] == false) { $parts = $this->getDateParts($this->mktime(0, 0, 0, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday -= $parts['mday']; } } } else { if ($calc == 'sub') { $date = $month - $date; $calc = 'set'; if (self::$_Options['extend_month'] == false) { $parts = $this->getDateParts($this->mktime(0, 0, 0, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday -= $parts['mday']; } } } } return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); } throw new Zend_Date_Exception("invalid date ({$date}) operand, month expected", $date); break; case Zend_Date::MONTH_NAME_SHORT: $monthlist = Zend_Locale_Data::getContent($locale, 'monthlist', array('gregorian', 'format', 'abbreviated')); $cnt = 0; foreach ($monthlist as $key => $value) { if (strtoupper($value) == strtoupper($date)) { $found = $key; break; } ++$cnt; } $date = array_search($date, $monthlist); // Monthname found if ($cnt < 12) { $fixday = 0; if ($calc == 'add') { $date += $found; $calc = 'set'; if (self::$_Options['extend_month'] == false) { $parts = $this->getDateParts($this->mktime(0, 0, 0, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday -= $parts['mday']; } } } else { if ($calc == 'sub') { $date = $month - $found; $calc = 'set'; if (self::$_Options['extend_month'] == false) { $parts = $this->getDateParts($this->mktime(0, 0, 0, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday -= $parts['mday']; } } } } return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); } // Monthname not found throw new Zend_Date_Exception("invalid date ({$date}) operand, month expected", $date); break; case Zend_Date::MONTH_SHORT: if (is_numeric($date)) { $fixday = 0; if ($calc == 'add') { $date += $month; $calc = 'set'; if (self::$_Options['extend_month'] == false) { $parts = $this->getDateParts($this->mktime(0, 0, 0, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday -= $parts['mday']; } } } else { if ($calc == 'sub') { $date = $month - $date; $calc = 'set'; if (self::$_Options['extend_month'] == false) { $parts = $this->getDateParts($this->mktime(0, 0, 0, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday -= $parts['mday']; } } } } return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); } throw new Zend_Date_Exception("invalid date ({$date}) operand, month expected", $date); break; case Zend_Date::MONTH_DAYS: throw new Zend_Date_Exception('month days not supported', $date); break; case Zend_Date::MONTH_NAME_NARROW: $monthlist = Zend_Locale_Data::getContent($locale, 'monthlist', array('gregorian', 'stand-alone', 'narrow')); $cnt = 0; foreach ($monthlist as $key => $value) { if (strtoupper($value) == strtoupper($date)) { $found = $key; break; } ++$cnt; } $date = array_search($date, $monthlist); // Monthname found if ($cnt < 12) { $fixday = 0; if ($calc == 'add') { $date += $found; $calc = 'set'; if (self::$_Options['extend_month'] == false) { $parts = $this->getDateParts($this->mktime(0, 0, 0, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday -= $parts['mday']; } } } else { if ($calc == 'sub') { $date = $month - $found; $calc = 'set'; if (self::$_Options['extend_month'] == false) { $parts = $this->getDateParts($this->mktime(0, 0, 0, $date, $day, $year, false)); if ($parts['mday'] != $day) { $fixday -= $parts['mday']; } } } } return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); } // Monthname not found throw new Zend_Date_Exception("invalid date ({$date}) operand, month expected", $date); break; // year formats // year formats case Zend_Date::LEAPYEAR: throw new Zend_Date_Exception('leap year not supported', $date); break; case Zend_Date::YEAR_8601: if (is_numeric($date)) { if ($calc == 'add') { $date += $year; $calc = 'set'; } else { if ($calc == 'sub') { $date = $year - $date; $calc = 'set'; } } return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, intval($date), true), $this->mktime(0, 0, 0, $month, $day, $year, true), false); } throw new Zend_Date_Exception("invalid date ({$date}) operand, year expected", $date); break; case Zend_Date::YEAR: if (is_numeric($date)) { if ($calc == 'add') { $date += $year; $calc = 'set'; } else { if ($calc == 'sub') { $date = $year - $date; $calc = 'set'; } } return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, intval($date), true), $this->mktime(0, 0, 0, $month, $day, $year, true), false); } throw new Zend_Date_Exception("invalid date ({$date}) operand, year expected", $date); break; case Zend_Date::YEAR_SHORT: if (is_numeric($date)) { $date = intval($date); if ($date >= 0 and $date <= 100 and $calc == 'set') { $date += 1900; if ($date < 1970) { $date += 100; } } if ($calc == 'add') { $date += $year; $calc = 'set'; } else { if ($calc == 'sub') { $date = $year - $date; $calc = 'set'; } } return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, $date, true), $this->mktime(0, 0, 0, $month, $day, $year, true), false); } throw new Zend_Date_Exception("invalid date ({$date}) operand, year expected", $date); break; case Zend_Date::YEAR_SHORT_8601: if (is_numeric($date)) { $date = intval($date); if ($date >= 0 and $date <= 100 and $calc == 'set') { $date += 1900; if ($date < 1970) { $date += 100; } } if ($calc == 'add') { $date += $year; $calc = 'set'; } else { if ($calc == 'sub') { $date = $year - $date; $calc = 'set'; } } return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, $date, true), $this->mktime(0, 0, 0, $month, $day, $year, true), false); } throw new Zend_Date_Exception("invalid date ({$date}) operand, year expected", $date); break; // time formats // time formats case Zend_Date::MERIDIEM: throw new Zend_Date_Exception('meridiem not supported', $date); break; case Zend_Date::SWATCH: if (is_numeric($date)) { $rest = intval($date); $hours = floor($rest * 24 / 1000); $rest = $rest - $hours * 1000 / 24; $minutes = floor($rest * 1440 / 1000); $rest = $rest - $minutes * 1000 / 1440; $seconds = floor($rest * 86400 / 1000); return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, 1, 1, 1970, true), $this->mktime($hour, $minute, $second, 1, 1, 1970, true), false); } throw new Zend_Date_Exception("invalid date ({$date}) operand, swatchstamp expected", $date); break; case Zend_Date::HOUR_SHORT_AM: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); } throw new Zend_Date_Exception("invalid date ({$date}) operand, hour expected", $date); break; case Zend_Date::HOUR_SHORT: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); } throw new Zend_Date_Exception("invalid date ({$date}) operand, hour expected", $date); break; case Zend_Date::HOUR_AM: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); } throw new Zend_Date_Exception("invalid date ({$date}) operand, hour expected", $date); break; case Zend_Date::HOUR: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); } throw new Zend_Date_Exception("invalid date ({$date}) operand, hour expected", $date); break; case Zend_Date::MINUTE: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(0, intval($date), 0, 1, 1, 1970, true), $this->mktime(0, $minute, 0, 1, 1, 1970, true), false); } throw new Zend_Date_Exception("invalid date ({$date}) operand, minute expected", $date); break; case Zend_Date::SECOND: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(0, 0, intval($date), 1, 1, 1970, true), $this->mktime(0, 0, $second, 1, 1, 1970, true), false); } throw new Zend_Date_Exception("invalid date ({$date}) operand, second expected", $date); break; case Zend_Date::MILLISECOND: if (is_numeric($date)) { switch ($calc) { case 'set': return $this->setMillisecond($date); break; case 'add': return $this->addMillisecond($date); break; case 'sub': return $this->subMillisecond($date); break; } return $this->compareMillisecond($date); } throw new Zend_Date_Exception("invalid date ({$date}) operand, milliseconds expected", $date); break; case Zend_Date::MINUTE_SHORT: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(0, intval($date), 0, 1, 1, 1970, true), $this->mktime(0, $minute, 0, 1, 1, 1970, true), false); } throw new Zend_Date_Exception("invalid date ({$date}) operand, minute expected", $date); break; case Zend_Date::SECOND_SHORT: if (is_numeric($date)) { return $this->_assign($calc, $this->mktime(0, 0, intval($date), 1, 1, 1970, true), $this->mktime(0, 0, $second, 1, 1, 1970, true), false); } throw new Zend_Date_Exception("invalid date ({$date}) operand, second expected", $date); break; // timezone formats // break intentionally omitted // timezone formats // break intentionally omitted case Zend_Date::TIMEZONE_NAME: case Zend_Date::TIMEZONE: case Zend_Date::TIMEZONE_SECS: throw new Zend_Date_Exception('timezone not supported', $date); break; case Zend_Date::DAYLIGHT: throw new Zend_Date_Exception('daylight not supported', $date); break; case Zend_Date::GMT_DIFF: case Zend_Date::GMT_DIFF_SEP: throw new Zend_Date_Exception('gmtdiff not supported', $date); break; // date strings // date strings case Zend_Date::ISO_8601: $next = 0; if (preg_match('/-\\d{4}-\\d{2}-\\d{2}/', $date, $datematch)) { // -yyyy-mm-dd $minus = true; $result = array('Y' => 1, 'M' => 6, 'd' => 9); $next = 11; } else { if (preg_match('/\\d{4}-\\d{2}-\\d{2}/', $date, $datematch)) { // yyyy-mm-dd $result = array('Y' => 0, 'M' => 5, 'd' => 8); $next = 10; } else { if (preg_match('/-\\d{2}-\\d{2}-\\d{2}/', $date, $datematch)) { // -yy-mm-dd $minus = true; $result = array('y' => 1, 'M' => 4, 'd' => 7); $next = 9; } else { if (preg_match('/\\d{2}-\\d{2}-\\d{2}/', $date, $datematch)) { // yy-mm-dd $result = array('y' => 0, 'M' => 3, 'd' => 6); $next = 8; } else { if (preg_match('/-\\d{8}/', $date, $datematch)) { // -yyyymmdd $minus = true; $result = array('Y' => 1, 'M' => 5, 'd' => 7); $next = 9; } else { if (preg_match('/\\d{8}/', $date, $datematch)) { // yyyymmdd $result = array('Y' => 0, 'M' => 4, 'd' => 6); $next = 8; } else { if (preg_match('/-\\d{6}/', $date, $datematch)) { // -yymmdd $minus = true; $result = array('y' => 1, 'M' => 3, 'd' => 5); $next = 7; } else { if (preg_match('/\\d{6}/', $date, $datematch)) { // yymmdd $result = array('y' => 0, 'M' => 2, 'd' => 4); $next = 6; } } } } } } } } if (strlen($date) > $next) { $date = substr($date, $next); // Thh:mm:ss if (preg_match('/[T,\\s]{1}\\d{2}:\\d{2}:\\d{2}/', $date, $timematch)) { // Thh:mm:ss | _hh:mm:ss $result['h'] = 1; $result['m'] = 4; $result['s'] = 7; $next += 9; } else { if (preg_match('/\\d{2}:\\d{2}:\\d{2}/', $date, $timematch)) { // hh:mm:ss $result['h'] = 0; $result['m'] = 3; $result['s'] = 6; $next += 8; } else { if (preg_match('/[T,\\s]{1}\\d{2}\\d{2}\\d{2}/', $date, $timematch)) { // Thhmmss | _hhmmss $result['h'] = 1; $result['m'] = 3; $result['s'] = 5; $next += 7; } else { if (preg_match('/\\d{2}\\d{2}\\d{2}/', $date, $timematch)) { // hhmmss | hhmmss $result['h'] = 0; $result['m'] = 2; $result['s'] = 4; $next += 6; } } } } } if (!isset($result)) { throw new Zend_Date_Exception("unsupported ISO8601 format ({$date})", $date); } if (isset($result['M'])) { if (isset($result['Y'])) { $years = substr($datematch[0], $result['Y'], 4); if (isset($minus)) { $years = 0 - $years; } } else { $years = substr($datematch[0], $result['y'], 2); if (isset($minus)) { $years = 0 - $years; } if ($years >= 0) { $years += 1900; if ($years < 1970) { $years += 100; } } } $months = substr($datematch[0], $result['M'], 2); $days = substr($datematch[0], $result['d'], 2); } else { $years = 1970; $months = 1; $days = 1; } if (isset($result['h'])) { $hours = substr($timematch[0], $result['h'], 2); $minutes = substr($timematch[0], $result['m'], 2); $seconds = substr($timematch[0], $result['s'], 2); } else { $hours = 0; $minutes = 0; $seconds = 0; } if ($calc == 'set') { --$months; --$month; --$days; --$day; $years -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, 1 + $months, 1 + $days, 1970 + $years, false), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, false), false); break; case Zend_Date::RFC_2822: $result = preg_match('/\\w{3},\\s\\d{2}\\s\\w{3}\\s\\d{4}\\s\\d{2}:\\d{2}:\\d{2}\\s\\+\\d{4}/', $date, $match); if (!$result) { throw new Zend_Date_Exception("no RFC 2822 format ({$date})", $date); } $days = substr($match[0], 5, 2); $months = $this->getDigitFromName(substr($match[0], 8, 3)); $years = substr($match[0], 12, 4); $hours = substr($match[0], 17, 2); $minutes = substr($match[0], 20, 2); $seconds = substr($match[0], 23, 2); if ($calc == 'set') { --$months; --$month; --$days; --$day; $years -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, 1 + $months, 1 + $days, 1970 + $years, false), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, false), false); break; case Zend_Date::TIMESTAMP: if (is_numeric($date)) { return $this->_assign($calc, $date, $this->getUnixTimestamp()); } throw new Zend_Date_Exception("invalid date ({$date}) operand, timestamp expected", $date); break; // additional formats // break intentionally omitted // additional formats // break intentionally omitted case Zend_Date::ERA: case Zend_Date::ERA_NAME: throw new Zend_Date_Exception('era not supported', $date); break; case Zend_Date::DATES: try { $parsed = Zend_Locale_Format::getDate($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true)); if ($calc == 'set') { --$parsed['month']; --$month; --$parsed['day']; --$day; $parsed['year'] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); } catch (Zend_Locale_Exception $e) { throw new Zend_Date_Exception($e->getMessage(), $date); } break; case Zend_Date::DATE_FULL: try { $format = Zend_Locale_Data::getContent($locale, 'dateformat', array('gregorian', 'full')); $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format['pattern'], 'format_type' => 'iso', 'locale' => $locale)); if ($calc == 'set') { --$parsed['month']; --$month; --$parsed['day']; --$day; $parsed['year'] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); } catch (Zend_Locale_Exception $e) { throw new Zend_Date_Exception($e->getMessage(), $date); } break; case Zend_Date::DATE_LONG: try { $format = Zend_Locale_Data::getContent($locale, 'dateformat', array('gregorian', 'long')); $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format['pattern'], 'format_type' => 'iso', 'locale' => $locale)); if ($calc == 'set') { --$parsed['month']; --$month; --$parsed['day']; --$day; $parsed['year'] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); } catch (Zend_Locale_Exception $e) { throw new Zend_Date_Exception($e->getMessage(), $date); } break; case Zend_Date::DATE_MEDIUM: try { $format = Zend_Locale_Data::getContent($locale, 'dateformat', array('gregorian', 'medium')); $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format['pattern'], 'format_type' => 'iso', 'locale' => $locale)); if ($calc == 'set') { --$parsed['month']; --$month; --$parsed['day']; --$day; $parsed['year'] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); } catch (Zend_Locale_Exception $e) { throw new Zend_Date_Exception($e->getMessage(), $date); } break; case Zend_Date::DATE_SHORT: try { $format = Zend_Locale_Data::getContent($locale, 'dateformat', array('gregorian', 'short')); $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format['pattern'], 'format_type' => 'iso', 'locale' => $locale)); if ($parsed['year'] < 100) { $parsed['year'] += 1900; if ($parsed['year'] < 1970) { $parsed['year'] += 100; } } if ($calc == 'set') { --$parsed['month']; --$month; --$parsed['day']; --$day; $parsed['year'] -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); } catch (Zend_Locale_Exception $e) { throw new Zend_Date_Exception($e->getMessage(), $date); } break; case Zend_Date::TIMES: try { if ($calc != 'set') { $month = 1; $day = 1; $year = 1970; } $parsed = Zend_Locale_Format::getTime($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true)); return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); } catch (Zend_Locale_Exception $e) { throw new Zend_Date_Exception($e->getMessage(), $date); } break; case Zend_Date::TIME_FULL: try { $format = Zend_Locale_Data::getContent($locale, 'timeformat', array('gregorian', 'full')); $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format['pattern'], 'format_type' => 'iso', 'locale' => $locale)); if ($calc != 'set') { $month = 1; $day = 1; $year = 1970; } return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], 0, $month, $day, $year, true), $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); } catch (Zend_Locale_Exception $e) { throw new Zend_Date_Exception($e->getMessage(), $date); } break; case Zend_Date::TIME_LONG: try { $format = Zend_Locale_Data::getContent($locale, 'timeformat', array('gregorian', 'long')); $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format['pattern'], 'format_type' => 'iso', 'locale' => $locale)); if ($calc != 'set') { $month = 1; $day = 1; $year = 1970; } return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); } catch (Zend_Locale_Exception $e) { throw new Zend_Date_Exception($e->getMessage(), $date); } break; case Zend_Date::TIME_MEDIUM: try { $format = Zend_Locale_Data::getContent($locale, 'timeformat', array('gregorian', 'medium')); $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format['pattern'], 'format_type' => 'iso', 'locale' => $locale)); if ($calc != 'set') { $month = 1; $day = 1; $year = 1970; } return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); } catch (Zend_Locale_Exception $e) { throw new Zend_Date_Exception($e->getMessage(), $date); } break; case Zend_Date::TIME_SHORT: try { $format = Zend_Locale_Data::getContent($locale, 'timeformat', array('gregorian', 'short')); $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format['pattern'], 'format_type' => 'iso', 'locale' => $locale)); if ($calc != 'set') { $month = 1; $day = 1; $year = 1970; } return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], 0, $month, $day, $year, true), $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); } catch (Zend_Locale_Exception $e) { throw new Zend_Date_Exception($e->getMessage(), $date); } break; // ATOM and RFC_3339 are identical // ATOM and RFC_3339 are identical case Zend_Date::ATOM: case Zend_Date::RFC_3339: $result = preg_match('/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}[+-]{1}\\d{2}:\\d{2}$/', $date, $match); if (!$result) { throw new Zend_Date_Exception("invalid date ({$date}) operand, ATOM format expected", $date); } $years = substr($match[0], 0, 4); $months = substr($match[0], 5, 2); $days = substr($match[0], 8, 2); $hours = substr($match[0], 11, 2); $minutes = substr($match[0], 14, 2); $seconds = substr($match[0], 17, 2); if ($calc == 'set') { --$months; --$month; --$days; --$day; $years -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, 1 + $months, 1 + $days, 1970 + $years, true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); break; case Zend_Date::COOKIE: $result = preg_match('/\\w{6,9},\\s\\d{2}-\\w{3}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}\\s\\w{3}/', $date, $match); if (!$result) { throw new Zend_Date_Exception("invalid date ({$date}) operand, COOKIE format expected", $date); } $match[0] = substr($match[0], strpos($match[0], ' ') + 1); $days = substr($match[0], 0, 2); $months = $this->getDigitFromName(substr($match[0], 3, 3)); $years = substr($match[0], 7, 4); $years += 2000; $hours = substr($match[0], 10, 2); $minutes = substr($match[0], 13, 2); $seconds = substr($match[0], 16, 2); if ($calc == 'set') { --$months; --$month; --$days; --$day; $years -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, 1 + $months, 1 + $days, 1970 + $years, true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); break; case Zend_Date::RFC_822: // new RFC 822 format $result = preg_match('/^\\w{3},\\s\\d{2}\\s\\w{3}\\s\\d{2}\\s\\d{2}:\\d{2}:\\d{2}\\s[+-]{1}\\d{4}$/', $date, $match); if (!$result) { // old RFC 822 format $result = preg_match('/\\w{3},\\s\\d{2}\\s\\w{3}\\s\\d{2}\\s\\d{2}:\\d{2}:\\d{2}\\s\\w{1,3}/', $date, $match); } if (!$result) { throw new Zend_Date_Exception("invalid date ({$date}) operand, RFC 822 date format expected", $date); } $days = substr($match[0], 5, 2); $months = $this->getDigitFromName(substr($match[0], 8, 3)); $years = substr($match[0], 12, 4); $years += 2000; $hours = substr($match[0], 15, 2); $minutes = substr($match[0], 18, 2); $seconds = substr($match[0], 21, 2); if ($calc == 'set') { --$months; --$month; --$days; --$day; $years -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, 1 + $months, 1 + $days, 1970 + $years, false), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, false), false); break; case Zend_Date::RFC_850: $result = preg_match('/\\w{6,9},\\s\\d{2}-\\w{3}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}\\s\\w{3}/', $date, $match); if (!$result) { throw new Zend_Date_Exception("invalid date ({$date}) operand, RFC 850 date format expected", $date); } $match[0] = substr($match[0], strpos($match[0], ' ') + 1); $days = substr($match[0], 0, 2); $months = $this->getDigitFromName(substr($match[0], 3, 3)); $years = substr($match[0], 7, 4); $years += 2000; $hours = substr($match[0], 10, 2); $minutes = substr($match[0], 13, 2); $seconds = substr($match[0], 16, 2); if ($calc == 'set') { --$months; --$month; --$days; --$day; $years -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, 1 + $months, 1 + $days, 1970 + $years, true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); break; case Zend_Date::RFC_1036: $result = preg_match('/^\\w{3},\\s\\d{2}\\s\\w{3}\\s\\d{2}\\s\\d{2}:\\d{2}:\\d{2}\\s[+-]{1}\\d{4}$/', $date, $match); if (!$result) { throw new Zend_Date_Exception("invalid date ({$date}) operand, RFC 1036 date format expected", $date); } $days = substr($match[0], 5, 2); $months = $this->getDigitFromName(substr($match[0], 8, 3)); $years = substr($match[0], 12, 4); $years += 2000; $hours = substr($match[0], 15, 2); $minutes = substr($match[0], 18, 2); $seconds = substr($match[0], 21, 2); if ($calc == 'set') { --$months; --$month; --$days; --$day; $years -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, 1 + $months, 1 + $days, 1970 + $years, true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); break; case Zend_Date::RFC_1123: $result = preg_match('/^\\w{3},\\s\\d{2}\\s\\w{3}\\s\\d{4}\\s\\d{2}:\\d{2}:\\d{2}\\s[+-]{1}\\d{4}$/', $date, $match); if (!$result) { throw new Zend_Date_Exception("invalid date ({$date}) operand, RFC 1123 date format expected", $date); } $days = substr($match[0], 5, 2); $months = $this->getDigitFromName(substr($match[0], 8, 3)); $years = substr($match[0], 12, 4); $hours = substr($match[0], 17, 2); $minutes = substr($match[0], 20, 2); $seconds = substr($match[0], 23, 2); if ($calc == 'set') { --$months; --$month; --$days; --$day; $years -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, 1 + $months, 1 + $days, 1970 + $years, true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); break; case Zend_Date::RSS: $result = preg_match('/^\\w{3},\\s\\d{2}\\s\\w{3}\\s\\d{4}\\s\\d{2}:\\d{2}:\\d{2}\\s[+-]{1}\\d{4}$/', $date, $match); if (!$result) { throw new Zend_Date_Exception("invalid date ({$date}) operand, RSS date format expected", $date); } $days = substr($match[0], 5, 2); $months = $this->getDigitFromName(substr($match[0], 8, 3)); $years = substr($match[0], 12, 4); $hours = substr($match[0], 17, 2); $minutes = substr($match[0], 20, 2); $seconds = substr($match[0], 23, 2); if ($calc == 'set') { --$months; --$month; --$days; --$day; $years -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, 1 + $months, 1 + $days, 1970 + $years, true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); break; case Zend_Date::W3C: $result = preg_match('/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}[+-]{1}\\d{2}:\\d{2}$/', $date, $match); if (!$result) { throw new Zend_Date_Exception("invalid date ({$date}) operand, W3C date format expected", $date); } $years = substr($match[0], 0, 4); $months = substr($match[0], 5, 2); $days = substr($match[0], 8, 2); $hours = substr($match[0], 11, 2); $minutes = substr($match[0], 14, 2); $seconds = substr($match[0], 17, 2); if ($calc == 'set') { --$months; --$month; --$days; --$day; $years -= 1970; $year -= 1970; } return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, 1 + $months, 1 + $days, 1970 + $years, true), $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); break; default: if (!is_numeric($date) || !empty($part)) { try { if (self::$_Options['format_type'] == 'php') { $part = Zend_Locale_Format::convertPhpToIsoFormat($part); } if (empty($part)) { $part = Zend_Locale_Format::getDateFormat($locale) . " "; $part .= Zend_Locale_Format::getTimeFormat($locale); } $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $part, 'locale' => $locale, 'fix_date' => true, 'format_type' => 'iso')); if ($calc == 'set') { if (isset($parsed['month'])) { --$parsed['month']; } else { $parsed['month'] = 0; } if (isset($parsed['day'])) { --$parsed['day']; } else { $parsed['day'] = 0; } if (isset($parsed['year'])) { $parsed['year'] -= 1970; } else { $parsed['year'] = 0; } } return $this->_assign($calc, $this->mktime(isset($parsed['hour']) ? $parsed['hour'] : 0, isset($parsed['minute']) ? $parsed['minute'] : 0, isset($parsed['second']) ? $parsed['second'] : 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], false), $this->getUnixTimestamp(), false); } catch (Zend_Locale_Exception $e) { if (!is_numeric($date)) { throw new Zend_Date_Exception($e->getMessage(), $date); } } } return $this->_assign($calc, $date, $this->getUnixTimestamp(), false); break; } }
/** * Test for mktime */ public function testMkTimeforDateValuesSmallerPHPRange() { $date = new Zend_Date_DateObject(); $this->assertSame($date->mktime(0, 0, 0, 1, 1, 1900, -1, false), -2208985200); $this->assertSame($date->mktime(0, 0, 0, 1, 1, 1900, -1, true), -2208988800); $this->assertSame($date->mktime(0, 0, 0, 1, 1, 1700, -1, false), -8520332400); $this->assertSame($date->mktime(0, 0, 0, 1, 1, 1700, -1, true), -8520336000); $this->assertSame($date->mktime(0, 0, 0, 1, 1, 1500, -1, false), -14830988400); $this->assertSame($date->mktime(0, 0, 0, 1, 1, 1500, -1, true), -14830992000); $this->assertSame($date->mktime(0, 0, 0, 10, 10, 1582, -1, false), -12219321600); $this->assertSame($date->mktime(0, 0, 0, 10, 10, 1582, -1, true), -12219321600); $this->assertSame($date->mktime(0, 0, 0, 1, 1, 1000, -1, false), -30609788400); $this->assertSame($date->mktime(0, 0, 0, 1, 1, 1000, -1, true), -30609792000); $this->assertSame($date->mktime(0, 0, 0, 1, 1, 0, -1, false), -62167388400); $this->assertSame($date->mktime(0, 0, 0, 1, 1, 0, -1, true), -62167392000); $this->assertSame($date->mktime(0, 0, 0, 1, 1, -2000, -1, false), -125282588400); $this->assertSame($date->mktime(0, 0, 0, 1, 1, -2000, -1, true), -125282592000); $this->assertSame($date->mktime(0, 0, 0, 13, 1, 1899, -1, false), -2208985200); $this->assertSame($date->mktime(0, 0, 0, 13, 1, 1899, -1, true), -2208988800); $this->assertSame($date->mktime(0, 0, 0, -11, 1, 1901, -1, false), -2208985200); $this->assertSame($date->mktime(0, 0, 0, -11, 1, 1901, -1, true), -2208988800); }