File indexing completed on 2024-12-22 05:37:16
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Date 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 * @version $Id$ 0020 */ 0021 0022 /** 0023 * Include needed Date classes 0024 */ 0025 // require_once 'Zend/Date/DateObject.php'; 0026 // require_once 'Zend/Locale.php'; 0027 // require_once 'Zend/Locale/Format.php'; 0028 // require_once 'Zend/Locale/Math.php'; 0029 0030 /** 0031 * @category Zend 0032 * @package Zend_Date 0033 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0034 * @license http://framework.zend.com/license/new-bsd New BSD License 0035 */ 0036 class Zend_Date extends Zend_Date_DateObject 0037 { 0038 private $_locale = null; 0039 0040 // Fractional second variables 0041 private $_fractional = 0; 0042 private $_precision = 3; 0043 0044 private static $_options = array( 0045 'format_type' => 'iso', // format for date strings 'iso' or 'php' 0046 'fix_dst' => true, // fix dst on summer/winter time change 0047 'extend_month' => false, // false - addMonth like SQL, true like excel 0048 'cache' => null, // cache to set 0049 'timesync' => null // timesync server to set 0050 ); 0051 0052 // Class wide Date Constants 0053 const DAY = 'dd'; 0054 const DAY_SHORT = 'd'; 0055 const DAY_SUFFIX = 'SS'; 0056 const DAY_OF_YEAR = 'D'; 0057 const WEEKDAY = 'EEEE'; 0058 const WEEKDAY_SHORT = 'EEE'; 0059 const WEEKDAY_NARROW = 'E'; 0060 const WEEKDAY_NAME = 'EE'; 0061 const WEEKDAY_8601 = 'eee'; 0062 const WEEKDAY_DIGIT = 'e'; 0063 const WEEK = 'ww'; 0064 const MONTH = 'MM'; 0065 const MONTH_SHORT = 'M'; 0066 const MONTH_DAYS = 'ddd'; 0067 const MONTH_NAME = 'MMMM'; 0068 const MONTH_NAME_SHORT = 'MMM'; 0069 const MONTH_NAME_NARROW = 'MMMMM'; 0070 const YEAR = 'y'; 0071 const YEAR_SHORT = 'yy'; 0072 const YEAR_8601 = 'Y'; 0073 const YEAR_SHORT_8601 = 'YY'; 0074 const LEAPYEAR = 'l'; 0075 const MERIDIEM = 'a'; 0076 const SWATCH = 'B'; 0077 const HOUR = 'HH'; 0078 const HOUR_SHORT = 'H'; 0079 const HOUR_AM = 'hh'; 0080 const HOUR_SHORT_AM = 'h'; 0081 const MINUTE = 'mm'; 0082 const MINUTE_SHORT = 'm'; 0083 const SECOND = 'ss'; 0084 const SECOND_SHORT = 's'; 0085 const MILLISECOND = 'S'; 0086 const TIMEZONE_NAME = 'zzzz'; 0087 const DAYLIGHT = 'I'; 0088 const GMT_DIFF = 'Z'; 0089 const GMT_DIFF_SEP = 'ZZZZ'; 0090 const TIMEZONE = 'z'; 0091 const TIMEZONE_SECS = 'X'; 0092 const ISO_8601 = 'c'; 0093 const RFC_2822 = 'r'; 0094 const TIMESTAMP = 'U'; 0095 const ERA = 'G'; 0096 const ERA_NAME = 'GGGG'; 0097 const ERA_NARROW = 'GGGGG'; 0098 const DATES = 'F'; 0099 const DATE_FULL = 'FFFFF'; 0100 const DATE_LONG = 'FFFF'; 0101 const DATE_MEDIUM = 'FFF'; 0102 const DATE_SHORT = 'FF'; 0103 const TIMES = 'WW'; 0104 const TIME_FULL = 'TTTTT'; 0105 const TIME_LONG = 'TTTT'; 0106 const TIME_MEDIUM = 'TTT'; 0107 const TIME_SHORT = 'TT'; 0108 const DATETIME = 'K'; 0109 const DATETIME_FULL = 'KKKKK'; 0110 const DATETIME_LONG = 'KKKK'; 0111 const DATETIME_MEDIUM = 'KKK'; 0112 const DATETIME_SHORT = 'KK'; 0113 const ATOM = 'OOO'; 0114 const COOKIE = 'CCC'; 0115 const RFC_822 = 'R'; 0116 const RFC_850 = 'RR'; 0117 const RFC_1036 = 'RRR'; 0118 const RFC_1123 = 'RRRR'; 0119 const RFC_3339 = 'RRRRR'; 0120 const RSS = 'SSS'; 0121 const W3C = 'WWW'; 0122 0123 /** 0124 * Generates the standard date object, could be a unix timestamp, localized date, 0125 * string, integer, array and so on. Also parts of dates or time are supported 0126 * Always set the default timezone: http://php.net/date_default_timezone_set 0127 * For example, in your bootstrap: date_default_timezone_set('America/Los_Angeles'); 0128 * For detailed instructions please look in the docu. 0129 * 0130 * @param string|integer|Zend_Date|array $date OPTIONAL Date value or value of date part to set 0131 * ,depending on $part. If null the actual time is set 0132 * @param string $part OPTIONAL Defines the input format of $date 0133 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 0134 * @return Zend_Date 0135 * @throws Zend_Date_Exception 0136 */ 0137 public function __construct($date = null, $part = null, $locale = null) 0138 { 0139 if (is_object($date) and !($date instanceof Zend_TimeSync_Protocol) and 0140 !($date instanceof Zend_Date)) { 0141 if ($locale instanceof Zend_Locale) { 0142 $locale = $date; 0143 $date = null; 0144 $part = null; 0145 } else { 0146 $date = (string) $date; 0147 } 0148 } 0149 0150 if (($date !== null) and !is_array($date) and !($date instanceof Zend_TimeSync_Protocol) and 0151 !($date instanceof Zend_Date) and !defined($date) and Zend_Locale::isLocale($date, true, false)) { 0152 $locale = $date; 0153 $date = null; 0154 $part = null; 0155 } else if (($part !== null) and !defined($part) and Zend_Locale::isLocale($part, true, false)) { 0156 $locale = $part; 0157 $part = null; 0158 } 0159 0160 $this->setLocale($locale); 0161 if (is_string($date) && ($part === null) && (strlen($date) <= 5)) { 0162 $part = $date; 0163 $date = null; 0164 } 0165 0166 if ($date === null) { 0167 if ($part === null) { 0168 $date = time(); 0169 } else if ($part !== self::TIMESTAMP) { 0170 $date = self::now($locale); 0171 $date = $date->get($part); 0172 } 0173 } 0174 0175 if ($date instanceof Zend_TimeSync_Protocol) { 0176 $date = $date->getInfo(); 0177 $date = $this->_getTime($date['offset']); 0178 $part = null; 0179 } else if (parent::$_defaultOffset != 0) { 0180 $date = $this->_getTime(parent::$_defaultOffset); 0181 } 0182 0183 // set the timezone and offset for $this 0184 $zone = @date_default_timezone_get(); 0185 $this->setTimezone($zone); 0186 0187 // try to get timezone from date-string 0188 if (!is_int($date)) { 0189 $zone = $this->getTimezoneFromString($date); 0190 $this->setTimezone($zone); 0191 } 0192 0193 // set datepart 0194 if (($part !== null && $part !== self::TIMESTAMP) or (!is_numeric($date))) { 0195 // switch off dst handling for value setting 0196 $this->setUnixTimestamp($this->getGmtOffset()); 0197 $this->set($date, $part, $this->_locale); 0198 0199 // DST fix 0200 if (is_array($date) === true) { 0201 if (!isset($date['hour'])) { 0202 $date['hour'] = 0; 0203 } 0204 0205 $hour = $this->toString('H', 'iso', true); 0206 $hour = $date['hour'] - $hour; 0207 switch ($hour) { 0208 case 1 : 0209 case -23 : 0210 $this->addTimestamp(3600); 0211 break; 0212 case -1 : 0213 case 23 : 0214 $this->subTimestamp(3600); 0215 break; 0216 case 2 : 0217 case -22 : 0218 $this->addTimestamp(7200); 0219 break; 0220 case -2 : 0221 case 22 : 0222 $this->subTimestamp(7200); 0223 break; 0224 } 0225 } 0226 } else { 0227 $this->setUnixTimestamp($date); 0228 } 0229 } 0230 0231 /** 0232 * Sets class wide options, if no option was given, the actual set options will be returned 0233 * 0234 * @param array $options Options to set 0235 * @throws Zend_Date_Exception 0236 * @return Options array if no option was given 0237 */ 0238 public static function setOptions(array $options = array()) 0239 { 0240 if (empty($options)) { 0241 return self::$_options; 0242 } 0243 0244 foreach ($options as $name => $value) { 0245 $name = strtolower($name); 0246 0247 if (array_key_exists($name, self::$_options)) { 0248 switch($name) { 0249 case 'format_type' : 0250 if ((strtolower($value) != 'php') && (strtolower($value) != 'iso')) { 0251 // require_once 'Zend/Date/Exception.php'; 0252 throw new Zend_Date_Exception("Unknown format type ($value) for dates, only 'iso' and 'php' supported", 0, null, $value); 0253 } 0254 break; 0255 case 'fix_dst' : 0256 if (!is_bool($value)) { 0257 // require_once 'Zend/Date/Exception.php'; 0258 throw new Zend_Date_Exception("'fix_dst' has to be boolean", 0, null, $value); 0259 } 0260 break; 0261 case 'extend_month' : 0262 if (!is_bool($value)) { 0263 // require_once 'Zend/Date/Exception.php'; 0264 throw new Zend_Date_Exception("'extend_month' has to be boolean", 0, null, $value); 0265 } 0266 break; 0267 case 'cache' : 0268 if ($value === null) { 0269 parent::$_cache = null; 0270 } else { 0271 if (!$value instanceof Zend_Cache_Core) { 0272 // require_once 'Zend/Date/Exception.php'; 0273 throw new Zend_Date_Exception("Instance of Zend_Cache expected"); 0274 } 0275 0276 parent::$_cache = $value; 0277 parent::$_cacheTags = Zend_Date_DateObject::_getTagSupportForCache(); 0278 Zend_Locale_Data::setCache($value); 0279 } 0280 break; 0281 case 'timesync' : 0282 if ($value === null) { 0283 parent::$_defaultOffset = 0; 0284 } else { 0285 if (!$value instanceof Zend_TimeSync_Protocol) { 0286 // require_once 'Zend/Date/Exception.php'; 0287 throw new Zend_Date_Exception("Instance of Zend_TimeSync expected"); 0288 } 0289 0290 $date = $value->getInfo(); 0291 parent::$_defaultOffset = $date['offset']; 0292 } 0293 break; 0294 } 0295 self::$_options[$name] = $value; 0296 } 0297 else { 0298 // require_once 'Zend/Date/Exception.php'; 0299 throw new Zend_Date_Exception("Unknown option: $name = $value"); 0300 } 0301 } 0302 } 0303 0304 /** 0305 * Returns this object's internal UNIX timestamp (equivalent to Zend_Date::TIMESTAMP). 0306 * If the timestamp is too large for integers, then the return value will be a string. 0307 * This function does not return the timestamp as an object. 0308 * Use clone() or copyPart() instead. 0309 * 0310 * @return integer|string UNIX timestamp 0311 */ 0312 public function getTimestamp() 0313 { 0314 return $this->getUnixTimestamp(); 0315 } 0316 0317 /** 0318 * Returns the calculated timestamp 0319 * HINT: timestamps are always GMT 0320 * 0321 * @param string $calc Type of calculation to make 0322 * @param string|integer|array|Zend_Date $stamp Timestamp to calculate, when null the actual timestamp is calculated 0323 * @return Zend_Date|integer 0324 * @throws Zend_Date_Exception 0325 */ 0326 private function _timestamp($calc, $stamp) 0327 { 0328 if ($stamp instanceof Zend_Date) { 0329 // extract timestamp from object 0330 $stamp = $stamp->getTimestamp(); 0331 } 0332 0333 if (is_array($stamp)) { 0334 if (isset($stamp['timestamp']) === true) { 0335 $stamp = $stamp['timestamp']; 0336 } else { 0337 // require_once 'Zend/Date/Exception.php'; 0338 throw new Zend_Date_Exception('no timestamp given in array'); 0339 } 0340 } 0341 0342 if ($calc === 'set') { 0343 $return = $this->setUnixTimestamp($stamp); 0344 } else { 0345 $return = $this->_calcdetail($calc, $stamp, self::TIMESTAMP, null); 0346 } 0347 if ($calc != 'cmp') { 0348 return $this; 0349 } 0350 return $return; 0351 } 0352 0353 /** 0354 * Sets a new timestamp 0355 * 0356 * @param integer|string|array|Zend_Date $timestamp Timestamp to set 0357 * @return Zend_Date Provides a fluent interface 0358 * @throws Zend_Date_Exception 0359 */ 0360 public function setTimestamp($timestamp) 0361 { 0362 return $this->_timestamp('set', $timestamp); 0363 } 0364 0365 /** 0366 * Adds a timestamp 0367 * 0368 * @param integer|string|array|Zend_Date $timestamp Timestamp to add 0369 * @return Zend_Date Provides a fluent interface 0370 * @throws Zend_Date_Exception 0371 */ 0372 public function addTimestamp($timestamp) 0373 { 0374 return $this->_timestamp('add', $timestamp); 0375 } 0376 0377 /** 0378 * Subtracts a timestamp 0379 * 0380 * @param integer|string|array|Zend_Date $timestamp Timestamp to sub 0381 * @return Zend_Date Provides a fluent interface 0382 * @throws Zend_Date_Exception 0383 */ 0384 public function subTimestamp($timestamp) 0385 { 0386 return $this->_timestamp('sub', $timestamp); 0387 } 0388 0389 /** 0390 * Compares two timestamps, returning the difference as integer 0391 * 0392 * @param integer|string|array|Zend_Date $timestamp Timestamp to compare 0393 * @return integer 0 = equal, 1 = later, -1 = earlier 0394 * @throws Zend_Date_Exception 0395 */ 0396 public function compareTimestamp($timestamp) 0397 { 0398 return $this->_timestamp('cmp', $timestamp); 0399 } 0400 0401 /** 0402 * Returns a string representation of the object 0403 * Supported format tokens are: 0404 * G - era, y - year, Y - ISO year, M - month, w - week of year, D - day of year, d - day of month 0405 * E - day of week, e - number of weekday (1-7), h - hour 1-12, H - hour 0-23, m - minute, s - second 0406 * A - milliseconds of day, z - timezone, Z - timezone offset, S - fractional second, a - period of day 0407 * 0408 * Additionally format tokens but non ISO conform are: 0409 * SS - day suffix, eee - php number of weekday(0-6), ddd - number of days per month 0410 * l - Leap year, B - swatch internet time, I - daylight saving time, X - timezone offset in seconds 0411 * r - RFC2822 format, U - unix timestamp 0412 * 0413 * Not supported ISO tokens are 0414 * u - extended year, Q - quarter, q - quarter, L - stand alone month, W - week of month 0415 * F - day of week of month, g - modified julian, c - stand alone weekday, k - hour 0-11, K - hour 1-24 0416 * v - wall zone 0417 * 0418 * @param string $format OPTIONAL Rule for formatting output. If null the default date format is used 0419 * @param string $type OPTIONAL Type for the format string which overrides the standard setting 0420 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 0421 * @return string 0422 */ 0423 public function toString($format = null, $type = null, $locale = null) 0424 { 0425 if (is_object($format)) { 0426 if ($format instanceof Zend_Locale) { 0427 $locale = $format; 0428 $format = null; 0429 } else { 0430 $format = (string) $format; 0431 } 0432 } 0433 0434 if (is_object($type)) { 0435 if ($type instanceof Zend_Locale) { 0436 $locale = $type; 0437 $type = null; 0438 } else { 0439 $type = (string) $type; 0440 } 0441 } 0442 0443 if (($format !== null) && !defined($format) 0444 && ($format != 'ee') && ($format != 'ss') && ($format != 'GG') && ($format != 'MM') && ($format != 'EE') && ($format != 'TT') 0445 && Zend_Locale::isLocale($format, null, false)) { 0446 $locale = $format; 0447 $format = null; 0448 } 0449 0450 if (($type !== null) and ($type != 'php') and ($type != 'iso') and 0451 Zend_Locale::isLocale($type, null, false)) { 0452 $locale = $type; 0453 $type = null; 0454 } 0455 0456 if ($locale === null) { 0457 $locale = $this->getLocale(); 0458 } 0459 0460 if ($format === null) { 0461 $format = Zend_Locale_Format::getDateFormat($locale) . ' ' . Zend_Locale_Format::getTimeFormat($locale); 0462 } else if (((self::$_options['format_type'] == 'php') && ($type === null)) or ($type == 'php')) { 0463 $format = Zend_Locale_Format::convertPhpToIsoFormat($format); 0464 } 0465 0466 return $this->date($this->_toToken($format, $locale), $this->getUnixTimestamp(), false); 0467 } 0468 0469 /** 0470 * Returns a string representation of the date which is equal with the timestamp 0471 * 0472 * @return string 0473 */ 0474 public function __toString() 0475 { 0476 return $this->toString(null, $this->_locale); 0477 } 0478 0479 /** 0480 * Returns a integer representation of the object 0481 * But returns false when the given part is no value f.e. Month-Name 0482 * 0483 * @param string|integer|Zend_Date $part OPTIONAL Defines the date or datepart to return as integer 0484 * @return integer|false 0485 */ 0486 public function toValue($part = null) 0487 { 0488 $result = $this->get($part); 0489 if (is_numeric($result)) { 0490 return intval("$result"); 0491 } else { 0492 return false; 0493 } 0494 } 0495 0496 /** 0497 * Returns an array representation of the object 0498 * 0499 * @return array 0500 */ 0501 public function toArray() 0502 { 0503 return array('day' => $this->toString(self::DAY_SHORT, 'iso'), 0504 'month' => $this->toString(self::MONTH_SHORT, 'iso'), 0505 'year' => $this->toString(self::YEAR, 'iso'), 0506 'hour' => $this->toString(self::HOUR_SHORT, 'iso'), 0507 'minute' => $this->toString(self::MINUTE_SHORT, 'iso'), 0508 'second' => $this->toString(self::SECOND_SHORT, 'iso'), 0509 'timezone' => $this->toString(self::TIMEZONE, 'iso'), 0510 'timestamp' => $this->toString(self::TIMESTAMP, 'iso'), 0511 'weekday' => $this->toString(self::WEEKDAY_8601, 'iso'), 0512 'dayofyear' => $this->toString(self::DAY_OF_YEAR, 'iso'), 0513 'week' => $this->toString(self::WEEK, 'iso'), 0514 'gmtsecs' => $this->toString(self::TIMEZONE_SECS, 'iso')); 0515 } 0516 0517 /** 0518 * Returns a representation of a date or datepart 0519 * This could be for example a localized monthname, the time without date, 0520 * the era or only the fractional seconds. There are about 50 different supported date parts. 0521 * For a complete list of supported datepart values look into the docu 0522 * 0523 * @param string $part OPTIONAL Part of the date to return, if null the timestamp is returned 0524 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 0525 * @return string date or datepart 0526 */ 0527 public function get($part = null, $locale = null) 0528 { 0529 if ($locale === null) { 0530 $locale = $this->getLocale(); 0531 } 0532 0533 if (($part !== null) && !defined($part) 0534 && ($part != 'ee') && ($part != 'ss') && ($part != 'GG') && ($part != 'MM') && ($part != 'EE') && ($part != 'TT') 0535 && Zend_Locale::isLocale($part, null, false)) { 0536 $locale = $part; 0537 $part = null; 0538 } 0539 0540 if ($part === null) { 0541 $part = self::TIMESTAMP; 0542 } else if (self::$_options['format_type'] == 'php') { 0543 $part = Zend_Locale_Format::convertPhpToIsoFormat($part); 0544 } 0545 0546 return $this->date($this->_toToken($part, $locale), $this->getUnixTimestamp(), false); 0547 } 0548 0549 /** 0550 * Internal method to apply tokens 0551 * 0552 * @param string $part 0553 * @param string $locale 0554 * @return string 0555 */ 0556 private function _toToken($part, $locale) { 0557 // get format tokens 0558 $comment = false; 0559 $format = ''; 0560 $orig = ''; 0561 for ($i = 0; isset($part[$i]); ++$i) { 0562 if ($part[$i] == "'") { 0563 $comment = $comment ? false : true; 0564 if (isset($part[$i+1]) && ($part[$i+1] == "'")) { 0565 $comment = $comment ? false : true; 0566 $format .= "\\'"; 0567 ++$i; 0568 } 0569 0570 $orig = ''; 0571 continue; 0572 } 0573 0574 if ($comment) { 0575 $format .= '\\' . $part[$i]; 0576 $orig = ''; 0577 } else { 0578 $orig .= $part[$i]; 0579 if (!isset($part[$i+1]) || (isset($orig[0]) && ($orig[0] != $part[$i+1]))) { 0580 $format .= $this->_parseIsoToDate($orig, $locale); 0581 $orig = ''; 0582 } 0583 } 0584 } 0585 0586 return $format; 0587 } 0588 0589 /** 0590 * Internal parsing method 0591 * 0592 * @param string $token 0593 * @param string $locale 0594 * @return string 0595 */ 0596 private function _parseIsoToDate($token, $locale) { 0597 switch($token) { 0598 case self::DAY : 0599 return 'd'; 0600 break; 0601 0602 case self::WEEKDAY_SHORT : 0603 $weekday = strtolower($this->date('D', $this->getUnixTimestamp(), false)); 0604 $day = Zend_Locale_Data::getContent($locale, 'day', array('gregorian', 'format', 'wide', $weekday)); 0605 return $this->_toComment(iconv_substr($day, 0, 3, 'UTF-8')); 0606 break; 0607 0608 case self::DAY_SHORT : 0609 return 'j'; 0610 break; 0611 0612 case self::WEEKDAY : 0613 $weekday = strtolower($this->date('D', $this->getUnixTimestamp(), false)); 0614 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'day', array('gregorian', 'format', 'wide', $weekday))); 0615 break; 0616 0617 case self::WEEKDAY_8601 : 0618 return 'N'; 0619 break; 0620 0621 case 'ee' : 0622 return $this->_toComment(str_pad($this->date('N', $this->getUnixTimestamp(), false), 2, '0', STR_PAD_LEFT)); 0623 break; 0624 0625 case self::DAY_SUFFIX : 0626 return 'S'; 0627 break; 0628 0629 case self::WEEKDAY_DIGIT : 0630 return 'w'; 0631 break; 0632 0633 case self::DAY_OF_YEAR : 0634 return 'z'; 0635 break; 0636 0637 case 'DDD' : 0638 return $this->_toComment(str_pad($this->date('z', $this->getUnixTimestamp(), false), 3, '0', STR_PAD_LEFT)); 0639 break; 0640 0641 case 'DD' : 0642 return $this->_toComment(str_pad($this->date('z', $this->getUnixTimestamp(), false), 2, '0', STR_PAD_LEFT)); 0643 break; 0644 0645 case self::WEEKDAY_NARROW : 0646 case 'EEEEE' : 0647 $weekday = strtolower($this->date('D', $this->getUnixTimestamp(), false)); 0648 $day = Zend_Locale_Data::getContent($locale, 'day', array('gregorian', 'format', 'abbreviated', $weekday)); 0649 return $this->_toComment(iconv_substr($day, 0, 1, 'UTF-8')); 0650 break; 0651 0652 case self::WEEKDAY_NAME : 0653 $weekday = strtolower($this->date('D', $this->getUnixTimestamp(), false)); 0654 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'day', array('gregorian', 'format', 'abbreviated', $weekday))); 0655 break; 0656 0657 case 'w' : 0658 $week = $this->date('W', $this->getUnixTimestamp(), false); 0659 return $this->_toComment(($week[0] == '0') ? $week[1] : $week); 0660 break; 0661 0662 case self::WEEK : 0663 return 'W'; 0664 break; 0665 0666 case self::MONTH_NAME : 0667 $month = $this->date('n', $this->getUnixTimestamp(), false); 0668 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'month', array('gregorian', 'format', 'wide', $month))); 0669 break; 0670 0671 case self::MONTH : 0672 return 'm'; 0673 break; 0674 0675 case self::MONTH_NAME_SHORT : 0676 $month = $this->date('n', $this->getUnixTimestamp(), false); 0677 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'month', array('gregorian', 'format', 'abbreviated', $month))); 0678 break; 0679 0680 case self::MONTH_SHORT : 0681 return 'n'; 0682 break; 0683 0684 case self::MONTH_DAYS : 0685 return 't'; 0686 break; 0687 0688 case self::MONTH_NAME_NARROW : 0689 $month = $this->date('n', $this->getUnixTimestamp(), false); 0690 $mon = Zend_Locale_Data::getContent($locale, 'month', array('gregorian', 'format', 'abbreviated', $month)); 0691 return $this->_toComment(iconv_substr($mon, 0, 1, 'UTF-8')); 0692 break; 0693 0694 case self::LEAPYEAR : 0695 return 'L'; 0696 break; 0697 0698 case self::YEAR_8601 : 0699 return 'o'; 0700 break; 0701 0702 case self::YEAR : 0703 return 'Y'; 0704 break; 0705 0706 case self::YEAR_SHORT : 0707 return 'y'; 0708 break; 0709 0710 case self::YEAR_SHORT_8601 : 0711 return $this->_toComment(substr($this->date('o', $this->getUnixTimestamp(), false), -2, 2)); 0712 break; 0713 0714 case self::MERIDIEM : 0715 $am = $this->date('a', $this->getUnixTimestamp(), false); 0716 if ($am == 'am') { 0717 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'am')); 0718 } 0719 0720 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'pm')); 0721 break; 0722 0723 case self::SWATCH : 0724 return 'B'; 0725 break; 0726 0727 case self::HOUR_SHORT_AM : 0728 return 'g'; 0729 break; 0730 0731 case self::HOUR_SHORT : 0732 return 'G'; 0733 break; 0734 0735 case self::HOUR_AM : 0736 return 'h'; 0737 break; 0738 0739 case self::HOUR : 0740 return 'H'; 0741 break; 0742 0743 case self::MINUTE : 0744 return $this->_toComment(str_pad($this->date('i', $this->getUnixTimestamp(), false), 2, '0', STR_PAD_LEFT)); 0745 break; 0746 0747 case self::SECOND : 0748 return $this->_toComment(str_pad($this->date('s', $this->getUnixTimestamp(), false), 2, '0', STR_PAD_LEFT)); 0749 break; 0750 0751 case self::MINUTE_SHORT : 0752 return 'i'; 0753 break; 0754 0755 case self::SECOND_SHORT : 0756 return 's'; 0757 break; 0758 0759 case self::MILLISECOND : 0760 return $this->_toComment($this->getMilliSecond()); 0761 break; 0762 0763 case self::TIMEZONE_NAME : 0764 case 'vvvv' : 0765 return 'e'; 0766 break; 0767 0768 case self::DAYLIGHT : 0769 return 'I'; 0770 break; 0771 0772 case self::GMT_DIFF : 0773 case 'ZZ' : 0774 case 'ZZZ' : 0775 return 'O'; 0776 break; 0777 0778 case self::GMT_DIFF_SEP : 0779 return 'P'; 0780 break; 0781 0782 case self::TIMEZONE : 0783 case 'v' : 0784 case 'zz' : 0785 case 'zzz' : 0786 return 'T'; 0787 break; 0788 0789 case self::TIMEZONE_SECS : 0790 return 'Z'; 0791 break; 0792 0793 case self::ISO_8601 : 0794 return 'c'; 0795 break; 0796 0797 case self::RFC_2822 : 0798 return 'r'; 0799 break; 0800 0801 case self::TIMESTAMP : 0802 return 'U'; 0803 break; 0804 0805 case self::ERA : 0806 case 'GG' : 0807 case 'GGG' : 0808 $year = $this->date('Y', $this->getUnixTimestamp(), false); 0809 if ($year < 0) { 0810 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Abbr', '0'))); 0811 } 0812 0813 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Abbr', '1'))); 0814 break; 0815 0816 case self::ERA_NARROW : 0817 $year = $this->date('Y', $this->getUnixTimestamp(), false); 0818 if ($year < 0) { 0819 return $this->_toComment(iconv_substr(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Abbr', '0')), 0, 1, 'UTF-8')) . '.'; 0820 } 0821 0822 return $this->_toComment(iconv_substr(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Abbr', '1')), 0, 1, 'UTF-8')) . '.'; 0823 break; 0824 0825 case self::ERA_NAME : 0826 $year = $this->date('Y', $this->getUnixTimestamp(), false); 0827 if ($year < 0) { 0828 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Names', '0'))); 0829 } 0830 0831 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Names', '1'))); 0832 break; 0833 0834 case self::DATES : 0835 return $this->_toToken(Zend_Locale_Format::getDateFormat($locale), $locale); 0836 break; 0837 0838 case self::DATE_FULL : 0839 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'full')), $locale); 0840 break; 0841 0842 case self::DATE_LONG : 0843 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'long')), $locale); 0844 break; 0845 0846 case self::DATE_MEDIUM : 0847 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'medium')), $locale); 0848 break; 0849 0850 case self::DATE_SHORT : 0851 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'short')), $locale); 0852 break; 0853 0854 case self::TIMES : 0855 return $this->_toToken(Zend_Locale_Format::getTimeFormat($locale), $locale); 0856 break; 0857 0858 case self::TIME_FULL : 0859 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'time', 'full'), $locale); 0860 break; 0861 0862 case self::TIME_LONG : 0863 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'time', 'long'), $locale); 0864 break; 0865 0866 case self::TIME_MEDIUM : 0867 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'time', 'medium'), $locale); 0868 break; 0869 0870 case self::TIME_SHORT : 0871 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'time', 'short'), $locale); 0872 break; 0873 0874 case self::DATETIME : 0875 return $this->_toToken(Zend_Locale_Format::getDateTimeFormat($locale), $locale); 0876 break; 0877 0878 case self::DATETIME_FULL : 0879 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'full')), $locale); 0880 break; 0881 0882 case self::DATETIME_LONG : 0883 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'long')), $locale); 0884 break; 0885 0886 case self::DATETIME_MEDIUM : 0887 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'medium')), $locale); 0888 break; 0889 0890 case self::DATETIME_SHORT : 0891 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'short')), $locale); 0892 break; 0893 0894 case self::ATOM : 0895 return 'Y\-m\-d\TH\:i\:sP'; 0896 break; 0897 0898 case self::COOKIE : 0899 return 'l\, d\-M\-y H\:i\:s e'; 0900 break; 0901 0902 case self::RFC_822 : 0903 return 'D\, d M y H\:i\:s O'; 0904 break; 0905 0906 case self::RFC_850 : 0907 return 'l\, d\-M\-y H\:i\:s e'; 0908 break; 0909 0910 case self::RFC_1036 : 0911 return 'D\, d M y H\:i\:s O'; 0912 break; 0913 0914 case self::RFC_1123 : 0915 return 'D\, d M Y H\:i\:s O'; 0916 break; 0917 0918 case self::RFC_3339 : 0919 return 'Y\-m\-d\TH\:i\:sP'; 0920 break; 0921 0922 case self::RSS : 0923 return 'D\, d M Y H\:i\:s O'; 0924 break; 0925 0926 case self::W3C : 0927 return 'Y\-m\-d\TH\:i\:sP'; 0928 break; 0929 } 0930 0931 if ($token == '') { 0932 return ''; 0933 } 0934 0935 switch ($token[0]) { 0936 case 'y' : 0937 if ((strlen($token) == 4) && (abs($this->getUnixTimestamp()) <= 0x7FFFFFFF)) { 0938 return 'Y'; 0939 } 0940 0941 $length = iconv_strlen($token, 'UTF-8'); 0942 return $this->_toComment(str_pad($this->date('Y', $this->getUnixTimestamp(), false), $length, '0', STR_PAD_LEFT)); 0943 break; 0944 0945 case 'Y' : 0946 if ((strlen($token) == 4) && (abs($this->getUnixTimestamp()) <= 0x7FFFFFFF)) { 0947 return 'o'; 0948 } 0949 0950 $length = iconv_strlen($token, 'UTF-8'); 0951 return $this->_toComment(str_pad($this->date('o', $this->getUnixTimestamp(), false), $length, '0', STR_PAD_LEFT)); 0952 break; 0953 0954 case 'A' : 0955 $length = iconv_strlen($token, 'UTF-8'); 0956 $result = substr($this->getMilliSecond(), 0, 3); 0957 $result += $this->date('s', $this->getUnixTimestamp(), false) * 1000; 0958 $result += $this->date('i', $this->getUnixTimestamp(), false) * 60000; 0959 $result += $this->date('H', $this->getUnixTimestamp(), false) * 3600000; 0960 0961 return $this->_toComment(str_pad($result, $length, '0', STR_PAD_LEFT)); 0962 break; 0963 } 0964 0965 return $this->_toComment($token); 0966 } 0967 0968 /** 0969 * Private function to make a comment of a token 0970 * 0971 * @param string $token 0972 * @return string 0973 */ 0974 private function _toComment($token) 0975 { 0976 $token = str_split($token); 0977 $result = ''; 0978 foreach ($token as $tok) { 0979 $result .= '\\' . $tok; 0980 } 0981 0982 return $result; 0983 } 0984 0985 /** 0986 * Return digit from standard names (english) 0987 * Faster implementation than locale aware searching 0988 * 0989 * @param string $name 0990 * @return integer Number of this month 0991 * @throws Zend_Date_Exception 0992 */ 0993 private function _getDigitFromName($name) 0994 { 0995 switch($name) { 0996 case "Jan": 0997 return 1; 0998 0999 case "Feb": 1000 return 2; 1001 1002 case "Mar": 1003 return 3; 1004 1005 case "Apr": 1006 return 4; 1007 1008 case "May": 1009 return 5; 1010 1011 case "Jun": 1012 return 6; 1013 1014 case "Jul": 1015 return 7; 1016 1017 case "Aug": 1018 return 8; 1019 1020 case "Sep": 1021 return 9; 1022 1023 case "Oct": 1024 return 10; 1025 1026 case "Nov": 1027 return 11; 1028 1029 case "Dec": 1030 return 12; 1031 1032 default: 1033 // require_once 'Zend/Date/Exception.php'; 1034 throw new Zend_Date_Exception('Month ($name) is not a known month'); 1035 } 1036 } 1037 1038 /** 1039 * Counts the exact year number 1040 * < 70 - 2000 added, >70 < 100 - 1900, others just returned 1041 * 1042 * @param integer $value year number 1043 * @return integer Number of year 1044 */ 1045 public static function getFullYear($value) 1046 { 1047 if ($value >= 0) { 1048 if ($value < 70) { 1049 $value += 2000; 1050 } else if ($value < 100) { 1051 $value += 1900; 1052 } 1053 } 1054 return $value; 1055 } 1056 1057 /** 1058 * Sets the given date as new date or a given datepart as new datepart returning the new datepart 1059 * This could be for example a localized dayname, the date without time, 1060 * the month or only the seconds. There are about 50 different supported date parts. 1061 * For a complete list of supported datepart values look into the docu 1062 * 1063 * @param string|integer|array|Zend_Date $date Date or datepart to set 1064 * @param string $part OPTIONAL Part of the date to set, if null the timestamp is set 1065 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 1066 * @return Zend_Date Provides a fluent interface 1067 * @throws Zend_Date_Exception 1068 */ 1069 public function set($date, $part = null, $locale = null) 1070 { 1071 if (self::$_options['format_type'] == 'php') { 1072 $part = Zend_Locale_Format::convertPhpToIsoFormat($part); 1073 } 1074 1075 $zone = $this->getTimezoneFromString($date); 1076 $this->setTimezone($zone); 1077 1078 $this->_calculate('set', $date, $part, $locale); 1079 return $this; 1080 } 1081 1082 /** 1083 * Adds a date or datepart to the existing date, by extracting $part from $date, 1084 * and modifying this object by adding that part. The $part is then extracted from 1085 * this object and returned as an integer or numeric string (for large values, or $part's 1086 * corresponding to pre-defined formatted date strings). 1087 * This could be for example a ISO 8601 date, the hour the monthname or only the minute. 1088 * There are about 50 different supported date parts. 1089 * For a complete list of supported datepart values look into the docu. 1090 * 1091 * @param string|integer|array|Zend_Date $date Date or datepart to add 1092 * @param string $part OPTIONAL Part of the date to add, if null the timestamp is added 1093 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 1094 * @return Zend_Date Provides a fluent interface 1095 * @throws Zend_Date_Exception 1096 */ 1097 public function add($date, $part = self::TIMESTAMP, $locale = null) 1098 { 1099 if (self::$_options['format_type'] == 'php') { 1100 $part = Zend_Locale_Format::convertPhpToIsoFormat($part); 1101 } 1102 1103 $this->_calculate('add', $date, $part, $locale); 1104 return $this; 1105 } 1106 1107 /** 1108 * Subtracts a date from another date. 1109 * This could be for example a RFC2822 date, the time, 1110 * the year or only the timestamp. There are about 50 different supported date parts. 1111 * For a complete list of supported datepart values look into the docu 1112 * Be aware: Adding -2 Months is not equal to Subtracting 2 Months !!! 1113 * 1114 * @param string|integer|array|Zend_Date $date Date or datepart to subtract 1115 * @param string $part OPTIONAL Part of the date to sub, if null the timestamp is subtracted 1116 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 1117 * @return Zend_Date Provides a fluent interface 1118 * @throws Zend_Date_Exception 1119 */ 1120 public function sub($date, $part = self::TIMESTAMP, $locale = null) 1121 { 1122 if (self::$_options['format_type'] == 'php') { 1123 $part = Zend_Locale_Format::convertPhpToIsoFormat($part); 1124 } 1125 1126 $this->_calculate('sub', $date, $part, $locale); 1127 return $this; 1128 } 1129 1130 /** 1131 * Compares a date or datepart with the existing one. 1132 * Returns -1 if earlier, 0 if equal and 1 if later. 1133 * 1134 * @param string|integer|array|Zend_Date $date Date or datepart to compare with the date object 1135 * @param string $part OPTIONAL Part of the date to compare, if null the timestamp is subtracted 1136 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 1137 * @return integer 0 = equal, 1 = later, -1 = earlier 1138 * @throws Zend_Date_Exception 1139 */ 1140 public function compare($date, $part = self::TIMESTAMP, $locale = null) 1141 { 1142 if (self::$_options['format_type'] == 'php') { 1143 $part = Zend_Locale_Format::convertPhpToIsoFormat($part); 1144 } 1145 1146 $compare = $this->_calculate('cmp', $date, $part, $locale); 1147 1148 if ($compare > 0) { 1149 return 1; 1150 } else if ($compare < 0) { 1151 return -1; 1152 } 1153 return 0; 1154 } 1155 1156 /** 1157 * Returns a new instance of Zend_Date with the selected part copied. 1158 * To make an exact copy, use PHP's clone keyword. 1159 * For a complete list of supported date part values look into the docu. 1160 * If a date part is copied, all other date parts are set to standard values. 1161 * For example: If only YEAR is copied, the returned date object is equal to 1162 * 01-01-YEAR 00:00:00 (01-01-1970 00:00:00 is equal to timestamp 0) 1163 * If only HOUR is copied, the returned date object is equal to 1164 * 01-01-1970 HOUR:00:00 (so $this contains a timestamp equal to a timestamp of 0 plus HOUR). 1165 * 1166 * @param string $part Part of the date to compare, if null the timestamp is subtracted 1167 * @param string|Zend_Locale $locale OPTIONAL New object's locale. No adjustments to timezone are made. 1168 * @return Zend_Date New clone with requested part 1169 */ 1170 public function copyPart($part, $locale = null) 1171 { 1172 $clone = clone $this; // copy all instance variables 1173 $clone->setUnixTimestamp(0); // except the timestamp 1174 if ($locale != null) { 1175 $clone->setLocale($locale); // set an other locale if selected 1176 } 1177 $clone->set($this, $part); 1178 return $clone; 1179 } 1180 1181 /** 1182 * Internal function, returns the offset of a given timezone 1183 * 1184 * @param string $zone 1185 * @return integer 1186 */ 1187 public function getTimezoneFromString($zone) 1188 { 1189 if (is_array($zone)) { 1190 return $this->getTimezone(); 1191 } 1192 1193 if ($zone instanceof Zend_Date) { 1194 return $zone->getTimezone(); 1195 } 1196 1197 $match = array(); 1198 preg_match('/\dZ$/', $zone, $match); 1199 if (!empty($match)) { 1200 return "Etc/UTC"; 1201 } 1202 1203 preg_match('/([+-]\d{2}):{0,1}\d{2}/', $zone, $match); 1204 if (!empty($match) and ($match[count($match) - 1] <= 14) and ($match[count($match) - 1] >= -12)) { 1205 $zone = "Etc/GMT"; 1206 $zone .= ($match[count($match) - 1] < 0) ? "+" : "-"; 1207 $zone .= (int) abs($match[count($match) - 1]); 1208 return $zone; 1209 } 1210 1211 preg_match('/([[:alpha:]\/_]{3,30})(?!.*([[:alpha:]\/]{3,30}))/', $zone, $match); 1212 try { 1213 if (!empty($match) and (!is_int($match[count($match) - 1]))) { 1214 $oldzone = $this->getTimezone(); 1215 $this->setTimezone($match[count($match) - 1]); 1216 $result = $this->getTimezone(); 1217 $this->setTimezone($oldzone); 1218 if ($result !== $oldzone) { 1219 return $match[count($match) - 1]; 1220 } 1221 } 1222 } catch (Exception $e) { 1223 // fall through 1224 } 1225 1226 return $this->getTimezone(); 1227 } 1228 1229 /** 1230 * Calculates the date or object 1231 * 1232 * @param string $calc Calculation to make 1233 * @param string|integer $date Date for calculation 1234 * @param string|integer $comp Second date for calculation 1235 * @param boolean|integer $dst Use dst correction if option is set 1236 * @return integer|string|Zend_Date new timestamp or Zend_Date depending on calculation 1237 */ 1238 private function _assign($calc, $date, $comp = 0, $dst = false) 1239 { 1240 switch ($calc) { 1241 case 'set' : 1242 if (!empty($comp)) { 1243 $this->setUnixTimestamp(call_user_func(Zend_Locale_Math::$sub, $this->getUnixTimestamp(), $comp)); 1244 } 1245 $this->setUnixTimestamp(call_user_func(Zend_Locale_Math::$add, $this->getUnixTimestamp(), $date)); 1246 $value = $this->getUnixTimestamp(); 1247 break; 1248 case 'add' : 1249 $this->setUnixTimestamp(call_user_func(Zend_Locale_Math::$add, $this->getUnixTimestamp(), $date)); 1250 $value = $this->getUnixTimestamp(); 1251 break; 1252 case 'sub' : 1253 $this->setUnixTimestamp(call_user_func(Zend_Locale_Math::$sub, $this->getUnixTimestamp(), $date)); 1254 $value = $this->getUnixTimestamp(); 1255 break; 1256 default : 1257 // cmp - compare 1258 return call_user_func(Zend_Locale_Math::$comp, $comp, $date); 1259 break; 1260 } 1261 1262 // dst-correction if 'fix_dst' = true and dst !== false but only for non UTC and non GMT 1263 if ((self::$_options['fix_dst'] === true) and ($dst !== false) and ($this->_dst === true)) { 1264 $hour = $this->toString(self::HOUR, 'iso'); 1265 if ($hour != $dst) { 1266 if (($dst == ($hour + 1)) or ($dst == ($hour - 23))) { 1267 $value += 3600; 1268 } else if (($dst == ($hour - 1)) or ($dst == ($hour + 23))) { 1269 $value -= 3600; 1270 } 1271 $this->setUnixTimestamp($value); 1272 } 1273 } 1274 return $this->getUnixTimestamp(); 1275 } 1276 1277 1278 /** 1279 * Calculates the date or object 1280 * 1281 * @param string $calc Calculation to make, one of: 'add'|'sub'|'cmp'|'copy'|'set' 1282 * @param string|integer|array|Zend_Date $date Date or datepart to calculate with 1283 * @param string $part Part of the date to calculate, if null the timestamp is used 1284 * @param string|Zend_Locale $locale Locale for parsing input 1285 * @return integer|string|Zend_Date new timestamp 1286 * @throws Zend_Date_Exception 1287 */ 1288 private function _calculate($calc, $date, $part, $locale) 1289 { 1290 if ($date === null) { 1291 // require_once 'Zend/Date/Exception.php'; 1292 throw new Zend_Date_Exception('parameter $date must be set, null is not allowed'); 1293 } 1294 1295 if (($part !== null) && (strlen($part) !== 2) && (Zend_Locale::isLocale($part, null, false))) { 1296 $locale = $part; 1297 $part = null; 1298 } 1299 1300 if ($locale === null) { 1301 $locale = $this->getLocale(); 1302 } 1303 1304 $locale = (string) $locale; 1305 1306 // Create date parts 1307 $year = $this->toString(self::YEAR, 'iso'); 1308 $month = $this->toString(self::MONTH_SHORT, 'iso'); 1309 $day = $this->toString(self::DAY_SHORT, 'iso'); 1310 $hour = $this->toString(self::HOUR_SHORT, 'iso'); 1311 $minute = $this->toString(self::MINUTE_SHORT, 'iso'); 1312 $second = $this->toString(self::SECOND_SHORT, 'iso'); 1313 // If object extract value 1314 if ($date instanceof Zend_Date) { 1315 $date = $date->toString($part, 'iso', $locale); 1316 } 1317 1318 if (is_array($date) === true) { 1319 if (empty($part) === false) { 1320 switch($part) { 1321 // Fall through 1322 case self::DAY: 1323 case self::DAY_SHORT: 1324 if (isset($date['day']) === true) { 1325 $date = $date['day']; 1326 } 1327 break; 1328 // Fall through 1329 case self::WEEKDAY_SHORT: 1330 case self::WEEKDAY: 1331 case self::WEEKDAY_8601: 1332 case self::WEEKDAY_DIGIT: 1333 case self::WEEKDAY_NARROW: 1334 case self::WEEKDAY_NAME: 1335 if (isset($date['weekday']) === true) { 1336 $date = $date['weekday']; 1337 $part = self::WEEKDAY_DIGIT; 1338 } 1339 break; 1340 case self::DAY_OF_YEAR: 1341 if (isset($date['day_of_year']) === true) { 1342 $date = $date['day_of_year']; 1343 } 1344 break; 1345 // Fall through 1346 case self::MONTH: 1347 case self::MONTH_SHORT: 1348 case self::MONTH_NAME: 1349 case self::MONTH_NAME_SHORT: 1350 case self::MONTH_NAME_NARROW: 1351 if (isset($date['month']) === true) { 1352 $date = $date['month']; 1353 } 1354 break; 1355 // Fall through 1356 case self::YEAR: 1357 case self::YEAR_SHORT: 1358 case self::YEAR_8601: 1359 case self::YEAR_SHORT_8601: 1360 if (isset($date['year']) === true) { 1361 $date = $date['year']; 1362 } 1363 break; 1364 // Fall through 1365 case self::HOUR: 1366 case self::HOUR_AM: 1367 case self::HOUR_SHORT: 1368 case self::HOUR_SHORT_AM: 1369 if (isset($date['hour']) === true) { 1370 $date = $date['hour']; 1371 } 1372 break; 1373 // Fall through 1374 case self::MINUTE: 1375 case self::MINUTE_SHORT: 1376 if (isset($date['minute']) === true) { 1377 $date = $date['minute']; 1378 } 1379 break; 1380 // Fall through 1381 case self::SECOND: 1382 case self::SECOND_SHORT: 1383 if (isset($date['second']) === true) { 1384 $date = $date['second']; 1385 } 1386 break; 1387 // Fall through 1388 case self::TIMEZONE: 1389 case self::TIMEZONE_NAME: 1390 if (isset($date['timezone']) === true) { 1391 $date = $date['timezone']; 1392 } 1393 break; 1394 case self::TIMESTAMP: 1395 if (isset($date['timestamp']) === true) { 1396 $date = $date['timestamp']; 1397 } 1398 break; 1399 case self::WEEK: 1400 if (isset($date['week']) === true) { 1401 $date = $date['week']; 1402 } 1403 break; 1404 case self::TIMEZONE_SECS: 1405 if (isset($date['gmtsecs']) === true) { 1406 $date = $date['gmtsecs']; 1407 } 1408 break; 1409 default: 1410 // require_once 'Zend/Date/Exception.php'; 1411 throw new Zend_Date_Exception("datepart for part ($part) not found in array"); 1412 break; 1413 } 1414 } else { 1415 $hours = 0; 1416 if (isset($date['hour']) === true) { 1417 $hours = $date['hour']; 1418 } 1419 $minutes = 0; 1420 if (isset($date['minute']) === true) { 1421 $minutes = $date['minute']; 1422 } 1423 $seconds = 0; 1424 if (isset($date['second']) === true) { 1425 $seconds = $date['second']; 1426 } 1427 $months = 0; 1428 if (isset($date['month']) === true) { 1429 $months = $date['month']; 1430 } 1431 $days = 0; 1432 if (isset($date['day']) === true) { 1433 $days = $date['day']; 1434 } 1435 $years = 0; 1436 if (isset($date['year']) === true) { 1437 $years = $date['year']; 1438 } 1439 return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, $months, $days, $years, true), 1440 $this->mktime($hour, $minute, $second, $month, $day, $year, true), $hour); 1441 } 1442 } 1443 1444 // $date as object, part of foreign date as own date 1445 switch($part) { 1446 1447 // day formats 1448 case self::DAY: 1449 if (is_numeric($date)) { 1450 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true), 1451 $this->mktime(0, 0, 0, 1, 1 + intval($day), 1970, true), $hour); 1452 } 1453 1454 // require_once 'Zend/Date/Exception.php'; 1455 throw new Zend_Date_Exception("invalid date ($date) operand, day expected", 0, null, $date); 1456 break; 1457 1458 case self::WEEKDAY_SHORT: 1459 $daylist = Zend_Locale_Data::getList($locale, 'day'); 1460 $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); 1461 $cnt = 0; 1462 1463 foreach ($daylist as $key => $value) { 1464 if (strtoupper(iconv_substr($value, 0, 3, 'UTF-8')) == strtoupper($date)) { 1465 $found = $cnt; 1466 break; 1467 } 1468 ++$cnt; 1469 } 1470 1471 // Weekday found 1472 if ($cnt < 7) { 1473 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), 1474 $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); 1475 } 1476 1477 // Weekday not found 1478 // require_once 'Zend/Date/Exception.php'; 1479 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); 1480 break; 1481 1482 case self::DAY_SHORT: 1483 if (is_numeric($date)) { 1484 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true), 1485 $this->mktime(0, 0, 0, 1, 1 + intval($day), 1970, true), $hour); 1486 } 1487 1488 // require_once 'Zend/Date/Exception.php'; 1489 throw new Zend_Date_Exception("invalid date ($date) operand, day expected", 0, null, $date); 1490 break; 1491 1492 case self::WEEKDAY: 1493 $daylist = Zend_Locale_Data::getList($locale, 'day'); 1494 $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); 1495 $cnt = 0; 1496 1497 foreach ($daylist as $key => $value) { 1498 if (strtoupper($value) == strtoupper($date)) { 1499 $found = $cnt; 1500 break; 1501 } 1502 ++$cnt; 1503 } 1504 1505 // Weekday found 1506 if ($cnt < 7) { 1507 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), 1508 $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); 1509 } 1510 1511 // Weekday not found 1512 // require_once 'Zend/Date/Exception.php'; 1513 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); 1514 break; 1515 1516 case self::WEEKDAY_8601: 1517 $weekday = (int) $this->toString(self::WEEKDAY_8601, 'iso', $locale); 1518 if ((intval($date) > 0) and (intval($date) < 8)) { 1519 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true), 1520 $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); 1521 } 1522 1523 // Weekday not found 1524 // require_once 'Zend/Date/Exception.php'; 1525 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); 1526 break; 1527 1528 case self::DAY_SUFFIX: 1529 // require_once 'Zend/Date/Exception.php'; 1530 throw new Zend_Date_Exception('day suffix not supported', 0, null, $date); 1531 break; 1532 1533 case self::WEEKDAY_DIGIT: 1534 $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); 1535 if (is_numeric($date) and (intval($date) >= 0) and (intval($date) < 7)) { 1536 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $date, 1970, true), 1537 $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); 1538 } 1539 1540 // Weekday not found 1541 // require_once 'Zend/Date/Exception.php'; 1542 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); 1543 break; 1544 1545 case self::DAY_OF_YEAR: 1546 if (is_numeric($date)) { 1547 if (($calc == 'add') || ($calc == 'sub')) { 1548 $year = 1970; 1549 ++$date; 1550 ++$day; 1551 } 1552 1553 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, $date, $year, true), 1554 $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); 1555 } 1556 1557 // require_once 'Zend/Date/Exception.php'; 1558 throw new Zend_Date_Exception("invalid date ($date) operand, day expected", 0, null, $date); 1559 break; 1560 1561 case self::WEEKDAY_NARROW: 1562 $daylist = Zend_Locale_Data::getList($locale, 'day', array('gregorian', 'format', 'abbreviated')); 1563 $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); 1564 $cnt = 0; 1565 foreach ($daylist as $key => $value) { 1566 if (strtoupper(iconv_substr($value, 0, 1, 'UTF-8')) == strtoupper($date)) { 1567 $found = $cnt; 1568 break; 1569 } 1570 ++$cnt; 1571 } 1572 1573 // Weekday found 1574 if ($cnt < 7) { 1575 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), 1576 $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); 1577 } 1578 1579 // Weekday not found 1580 // require_once 'Zend/Date/Exception.php'; 1581 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); 1582 break; 1583 1584 case self::WEEKDAY_NAME: 1585 $daylist = Zend_Locale_Data::getList($locale, 'day', array('gregorian', 'format', 'abbreviated')); 1586 $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); 1587 $cnt = 0; 1588 foreach ($daylist as $key => $value) { 1589 if (strtoupper($value) == strtoupper($date)) { 1590 $found = $cnt; 1591 break; 1592 } 1593 ++$cnt; 1594 } 1595 1596 // Weekday found 1597 if ($cnt < 7) { 1598 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), 1599 $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); 1600 } 1601 1602 // Weekday not found 1603 // require_once 'Zend/Date/Exception.php'; 1604 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); 1605 break; 1606 1607 // week formats 1608 case self::WEEK: 1609 if (is_numeric($date)) { 1610 $week = (int) $this->toString(self::WEEK, 'iso', $locale); 1611 return $this->_assign($calc, parent::mktime(0, 0, 0, 1, 1 + ($date * 7), 1970, true), 1612 parent::mktime(0, 0, 0, 1, 1 + ($week * 7), 1970, true), $hour); 1613 } 1614 1615 // require_once 'Zend/Date/Exception.php'; 1616 throw new Zend_Date_Exception("invalid date ($date) operand, week expected", 0, null, $date); 1617 break; 1618 1619 // month formats 1620 case self::MONTH_NAME: 1621 $monthlist = Zend_Locale_Data::getList($locale, 'month'); 1622 $cnt = 0; 1623 foreach ($monthlist as $key => $value) { 1624 if (strtoupper($value) == strtoupper($date)) { 1625 $found = $key; 1626 break; 1627 } 1628 ++$cnt; 1629 } 1630 $date = array_search($date, $monthlist); 1631 1632 // Monthname found 1633 if ($cnt < 12) { 1634 $fixday = 0; 1635 if ($calc == 'add') { 1636 $date += $found; 1637 $calc = 'set'; 1638 if (self::$_options['extend_month'] == false) { 1639 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1640 if ($parts['mday'] != $day) { 1641 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1642 } 1643 } 1644 } else if ($calc == 'sub') { 1645 $date = $month - $found; 1646 $calc = 'set'; 1647 if (self::$_options['extend_month'] == false) { 1648 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1649 if ($parts['mday'] != $day) { 1650 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1651 } 1652 } 1653 } 1654 return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), 1655 $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); 1656 } 1657 1658 // Monthname not found 1659 // require_once 'Zend/Date/Exception.php'; 1660 throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date); 1661 break; 1662 1663 case self::MONTH: 1664 if (is_numeric($date)) { 1665 $fixday = 0; 1666 if ($calc == 'add') { 1667 $date += $month; 1668 $calc = 'set'; 1669 if (self::$_options['extend_month'] == false) { 1670 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1671 if ($parts['mday'] != $day) { 1672 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1673 } 1674 } 1675 } else if ($calc == 'sub') { 1676 $date = $month - $date; 1677 $calc = 'set'; 1678 if (self::$_options['extend_month'] == false) { 1679 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1680 if ($parts['mday'] != $day) { 1681 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1682 } 1683 } 1684 } 1685 return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), 1686 $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); 1687 } 1688 1689 // require_once 'Zend/Date/Exception.php'; 1690 throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date); 1691 break; 1692 1693 case self::MONTH_NAME_SHORT: 1694 $monthlist = Zend_Locale_Data::getList($locale, 'month', array('gregorian', 'format', 'abbreviated')); 1695 $cnt = 0; 1696 foreach ($monthlist as $key => $value) { 1697 if (strtoupper($value) == strtoupper($date)) { 1698 $found = $key; 1699 break; 1700 } 1701 ++$cnt; 1702 } 1703 $date = array_search($date, $monthlist); 1704 1705 // Monthname found 1706 if ($cnt < 12) { 1707 $fixday = 0; 1708 if ($calc == 'add') { 1709 $date += $found; 1710 $calc = 'set'; 1711 if (self::$_options['extend_month'] === false) { 1712 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1713 if ($parts['mday'] != $day) { 1714 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1715 } 1716 } 1717 } else if ($calc == 'sub') { 1718 $date = $month - $found; 1719 $calc = 'set'; 1720 if (self::$_options['extend_month'] === false) { 1721 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1722 if ($parts['mday'] != $day) { 1723 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1724 } 1725 } 1726 } 1727 return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), 1728 $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); 1729 } 1730 1731 // Monthname not found 1732 // require_once 'Zend/Date/Exception.php'; 1733 throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date); 1734 break; 1735 1736 case self::MONTH_SHORT: 1737 if (is_numeric($date) === true) { 1738 $fixday = 0; 1739 if ($calc === 'add') { 1740 $date += $month; 1741 $calc = 'set'; 1742 if (self::$_options['extend_month'] === false) { 1743 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1744 if ($parts['mday'] != $day) { 1745 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1746 } 1747 } 1748 } else if ($calc === 'sub') { 1749 $date = $month - $date; 1750 $calc = 'set'; 1751 if (self::$_options['extend_month'] === false) { 1752 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1753 if ($parts['mday'] != $day) { 1754 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1755 } 1756 } 1757 } 1758 1759 return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), 1760 $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); 1761 } 1762 1763 // require_once 'Zend/Date/Exception.php'; 1764 throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date); 1765 break; 1766 1767 case self::MONTH_DAYS: 1768 // require_once 'Zend/Date/Exception.php'; 1769 throw new Zend_Date_Exception('month days not supported', 0, null, $date); 1770 break; 1771 1772 case self::MONTH_NAME_NARROW: 1773 $monthlist = Zend_Locale_Data::getList($locale, 'month', array('gregorian', 'stand-alone', 'narrow')); 1774 $cnt = 0; 1775 foreach ($monthlist as $key => $value) { 1776 if (strtoupper($value) === strtoupper($date)) { 1777 $found = $key; 1778 break; 1779 } 1780 ++$cnt; 1781 } 1782 $date = array_search($date, $monthlist); 1783 1784 // Monthname found 1785 if ($cnt < 12) { 1786 $fixday = 0; 1787 if ($calc === 'add') { 1788 $date += $found; 1789 $calc = 'set'; 1790 if (self::$_options['extend_month'] === false) { 1791 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1792 if ($parts['mday'] != $day) { 1793 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1794 } 1795 } 1796 } else if ($calc === 'sub') { 1797 $date = $month - $found; 1798 $calc = 'set'; 1799 if (self::$_options['extend_month'] === false) { 1800 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1801 if ($parts['mday'] != $day) { 1802 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1803 } 1804 } 1805 } 1806 return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), 1807 $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); 1808 } 1809 1810 // Monthname not found 1811 // require_once 'Zend/Date/Exception.php'; 1812 throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date); 1813 break; 1814 1815 // year formats 1816 case self::LEAPYEAR: 1817 // require_once 'Zend/Date/Exception.php'; 1818 throw new Zend_Date_Exception('leap year not supported', 0, null, $date); 1819 break; 1820 1821 case self::YEAR_8601: 1822 if (is_numeric($date)) { 1823 if ($calc === 'add') { 1824 $date += $year; 1825 $calc = 'set'; 1826 } else if ($calc === 'sub') { 1827 $date = $year - $date; 1828 $calc = 'set'; 1829 } 1830 1831 return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, intval($date), true), 1832 $this->mktime(0, 0, 0, $month, $day, $year, true), false); 1833 } 1834 1835 // require_once 'Zend/Date/Exception.php'; 1836 throw new Zend_Date_Exception("invalid date ($date) operand, year expected", 0, null, $date); 1837 break; 1838 1839 case self::YEAR: 1840 if (is_numeric($date)) { 1841 if ($calc === 'add') { 1842 $date += $year; 1843 $calc = 'set'; 1844 } else if ($calc === 'sub') { 1845 $date = $year - $date; 1846 $calc = 'set'; 1847 } 1848 1849 return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, intval($date), true), 1850 $this->mktime(0, 0, 0, $month, $day, $year, true), false); 1851 } 1852 1853 // require_once 'Zend/Date/Exception.php'; 1854 throw new Zend_Date_Exception("invalid date ($date) operand, year expected", 0, null, $date); 1855 break; 1856 1857 case self::YEAR_SHORT: 1858 if (is_numeric($date)) { 1859 $date = intval($date); 1860 if (($calc == 'set') || ($calc == 'cmp')) { 1861 $date = self::getFullYear($date); 1862 } 1863 if ($calc === 'add') { 1864 $date += $year; 1865 $calc = 'set'; 1866 } else if ($calc === 'sub') { 1867 $date = $year - $date; 1868 $calc = 'set'; 1869 } 1870 1871 return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, $date, true), 1872 $this->mktime(0, 0, 0, $month, $day, $year, true), false); 1873 } 1874 1875 // require_once 'Zend/Date/Exception.php'; 1876 throw new Zend_Date_Exception("invalid date ($date) operand, year expected", 0, null, $date); 1877 break; 1878 1879 case self::YEAR_SHORT_8601: 1880 if (is_numeric($date)) { 1881 $date = intval($date); 1882 if (($calc === 'set') || ($calc === 'cmp')) { 1883 $date = self::getFullYear($date); 1884 } 1885 if ($calc === 'add') { 1886 $date += $year; 1887 $calc = 'set'; 1888 } else if ($calc === 'sub') { 1889 $date = $year - $date; 1890 $calc = 'set'; 1891 } 1892 1893 return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, $date, true), 1894 $this->mktime(0, 0, 0, $month, $day, $year, true), false); 1895 } 1896 1897 // require_once 'Zend/Date/Exception.php'; 1898 throw new Zend_Date_Exception("invalid date ($date) operand, year expected", 0, null, $date); 1899 break; 1900 1901 // time formats 1902 case self::MERIDIEM: 1903 // require_once 'Zend/Date/Exception.php'; 1904 throw new Zend_Date_Exception('meridiem not supported', 0, null, $date); 1905 break; 1906 1907 case self::SWATCH: 1908 if (is_numeric($date)) { 1909 $rest = intval($date); 1910 $hours = floor($rest * 24 / 1000); 1911 $rest = $rest - ($hours * 1000 / 24); 1912 $minutes = floor($rest * 1440 / 1000); 1913 $rest = $rest - ($minutes * 1000 / 1440); 1914 $seconds = floor($rest * 86400 / 1000); 1915 return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, 1, 1, 1970, true), 1916 $this->mktime($hour, $minute, $second, 1, 1, 1970, true), false); 1917 } 1918 1919 // require_once 'Zend/Date/Exception.php'; 1920 throw new Zend_Date_Exception("invalid date ($date) operand, swatchstamp expected", 0, null, $date); 1921 break; 1922 1923 case self::HOUR_SHORT_AM: 1924 if (is_numeric($date)) { 1925 return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), 1926 $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); 1927 } 1928 1929 // require_once 'Zend/Date/Exception.php'; 1930 throw new Zend_Date_Exception("invalid date ($date) operand, hour expected", 0, null, $date); 1931 break; 1932 1933 case self::HOUR_SHORT: 1934 if (is_numeric($date)) { 1935 return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), 1936 $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); 1937 } 1938 1939 // require_once 'Zend/Date/Exception.php'; 1940 throw new Zend_Date_Exception("invalid date ($date) operand, hour expected", 0, null, $date); 1941 break; 1942 1943 case self::HOUR_AM: 1944 if (is_numeric($date)) { 1945 return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), 1946 $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); 1947 } 1948 1949 // require_once 'Zend/Date/Exception.php'; 1950 throw new Zend_Date_Exception("invalid date ($date) operand, hour expected", 0, null, $date); 1951 break; 1952 1953 case self::HOUR: 1954 if (is_numeric($date)) { 1955 return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), 1956 $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); 1957 } 1958 1959 // require_once 'Zend/Date/Exception.php'; 1960 throw new Zend_Date_Exception("invalid date ($date) operand, hour expected", 0, null, $date); 1961 break; 1962 1963 case self::MINUTE: 1964 if (is_numeric($date)) { 1965 return $this->_assign($calc, $this->mktime(0, intval($date), 0, 1, 1, 1970, true), 1966 $this->mktime(0, $minute, 0, 1, 1, 1970, true), false); 1967 } 1968 1969 // require_once 'Zend/Date/Exception.php'; 1970 throw new Zend_Date_Exception("invalid date ($date) operand, minute expected", 0, null, $date); 1971 break; 1972 1973 case self::SECOND: 1974 if (is_numeric($date)) { 1975 return $this->_assign($calc, $this->mktime(0, 0, intval($date), 1, 1, 1970, true), 1976 $this->mktime(0, 0, $second, 1, 1, 1970, true), false); 1977 } 1978 1979 // require_once 'Zend/Date/Exception.php'; 1980 throw new Zend_Date_Exception("invalid date ($date) operand, second expected", 0, null, $date); 1981 break; 1982 1983 case self::MILLISECOND: 1984 if (is_numeric($date)) { 1985 switch($calc) { 1986 case 'set' : 1987 return $this->setMillisecond($date); 1988 break; 1989 case 'add' : 1990 return $this->addMillisecond($date); 1991 break; 1992 case 'sub' : 1993 return $this->subMillisecond($date); 1994 break; 1995 } 1996 1997 return $this->compareMillisecond($date); 1998 } 1999 2000 // require_once 'Zend/Date/Exception.php'; 2001 throw new Zend_Date_Exception("invalid date ($date) operand, milliseconds expected", 0, null, $date); 2002 break; 2003 2004 case self::MINUTE_SHORT: 2005 if (is_numeric($date)) { 2006 return $this->_assign($calc, $this->mktime(0, intval($date), 0, 1, 1, 1970, true), 2007 $this->mktime(0, $minute, 0, 1, 1, 1970, true), false); 2008 } 2009 2010 // require_once 'Zend/Date/Exception.php'; 2011 throw new Zend_Date_Exception("invalid date ($date) operand, minute expected", 0, null, $date); 2012 break; 2013 2014 case self::SECOND_SHORT: 2015 if (is_numeric($date)) { 2016 return $this->_assign($calc, $this->mktime(0, 0, intval($date), 1, 1, 1970, true), 2017 $this->mktime(0, 0, $second, 1, 1, 1970, true), false); 2018 } 2019 2020 // require_once 'Zend/Date/Exception.php'; 2021 throw new Zend_Date_Exception("invalid date ($date) operand, second expected", 0, null, $date); 2022 break; 2023 2024 // timezone formats 2025 // break intentionally omitted 2026 case self::TIMEZONE_NAME: 2027 case self::TIMEZONE: 2028 case self::TIMEZONE_SECS: 2029 // require_once 'Zend/Date/Exception.php'; 2030 throw new Zend_Date_Exception('timezone not supported', 0, null, $date); 2031 break; 2032 2033 case self::DAYLIGHT: 2034 // require_once 'Zend/Date/Exception.php'; 2035 throw new Zend_Date_Exception('daylight not supported', 0, null, $date); 2036 break; 2037 2038 case self::GMT_DIFF: 2039 case self::GMT_DIFF_SEP: 2040 // require_once 'Zend/Date/Exception.php'; 2041 throw new Zend_Date_Exception('gmtdiff not supported', 0, null, $date); 2042 break; 2043 2044 // date strings 2045 case self::ISO_8601: 2046 // (-)YYYY-MM-dd 2047 preg_match('/^(-{0,1}\d{4})-(\d{2})-(\d{2})/', $date, $datematch); 2048 // (-)YY-MM-dd 2049 if (empty($datematch)) { 2050 preg_match('/^(-{0,1}\d{2})-(\d{2})-(\d{2})/', $date, $datematch); 2051 } 2052 // (-)YYYYMMdd 2053 if (empty($datematch)) { 2054 preg_match('/^(-{0,1}\d{4})(\d{2})(\d{2})/', $date, $datematch); 2055 } 2056 // (-)YYMMdd 2057 if (empty($datematch)) { 2058 preg_match('/^(-{0,1}\d{2})(\d{2})(\d{2})/', $date, $datematch); 2059 } 2060 $tmpdate = $date; 2061 if (!empty($datematch)) { 2062 $dateMatchCharCount = iconv_strlen($datematch[0], 'UTF-8'); 2063 $tmpdate = iconv_substr($date, 2064 $dateMatchCharCount, 2065 iconv_strlen($date, 'UTF-8') - $dateMatchCharCount, 2066 'UTF-8'); 2067 } 2068 // (T)hh:mm:ss 2069 preg_match('/[T,\s]{0,1}(\d{2}):(\d{2}):(\d{2})/', $tmpdate, $timematch); 2070 // (T)hhmmss 2071 if (empty($timematch)) { 2072 preg_match('/[T,\s]{0,1}(\d{2})(\d{2})(\d{2})/', $tmpdate, $timematch); 2073 } 2074 // (T)hh:mm 2075 if (empty($timematch)) { 2076 preg_match('/[T,\s]{0,1}(\d{2}):(\d{2})/', $tmpdate, $timematch); 2077 } 2078 // (T)hhmm 2079 if (empty($timematch)) { 2080 preg_match('/[T,\s]{0,1}(\d{2})(\d{2})/', $tmpdate, $timematch); 2081 } 2082 if (empty($datematch) and empty($timematch)) { 2083 // require_once 'Zend/Date/Exception.php'; 2084 throw new Zend_Date_Exception("unsupported ISO8601 format ($date)", 0, null, $date); 2085 } 2086 if (!empty($timematch)) { 2087 $timeMatchCharCount = iconv_strlen($timematch[0], 'UTF-8'); 2088 $tmpdate = iconv_substr($tmpdate, 2089 $timeMatchCharCount, 2090 iconv_strlen($tmpdate, 'UTF-8') - $timeMatchCharCount, 2091 'UTF-8'); 2092 } 2093 if (empty($datematch)) { 2094 $datematch[1] = 1970; 2095 $datematch[2] = 1; 2096 $datematch[3] = 1; 2097 } else if (iconv_strlen($datematch[1], 'UTF-8') == 2) { 2098 $datematch[1] = self::getFullYear($datematch[1]); 2099 } 2100 if (empty($timematch)) { 2101 $timematch[1] = 0; 2102 $timematch[2] = 0; 2103 $timematch[3] = 0; 2104 } 2105 if (!isset($timematch[3])) { 2106 $timematch[3] = 0; 2107 } 2108 2109 if (($calc == 'set') || ($calc == 'cmp')) { 2110 --$datematch[2]; 2111 --$month; 2112 --$datematch[3]; 2113 --$day; 2114 $datematch[1] -= 1970; 2115 $year -= 1970; 2116 } 2117 return $this->_assign($calc, $this->mktime($timematch[1], $timematch[2], $timematch[3], 1 + $datematch[2], 1 + $datematch[3], 1970 + $datematch[1], false), 2118 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, false), false); 2119 break; 2120 2121 case self::RFC_2822: 2122 $result = preg_match('/^\w{3},\s(\d{1,2})\s(\w{3})\s(\d{4})\s' 2123 . '(\d{2}):(\d{2}):{0,1}(\d{0,2})\s([+-]' 2124 . '{1}\d{4}|\w{1,20})$/', $date, $match); 2125 2126 if (!$result) { 2127 // require_once 'Zend/Date/Exception.php'; 2128 throw new Zend_Date_Exception("no RFC 2822 format ($date)", 0, null, $date); 2129 } 2130 2131 $months = $this->_getDigitFromName($match[2]); 2132 2133 if (($calc == 'set') || ($calc == 'cmp')) { 2134 --$months; 2135 --$month; 2136 --$match[1]; 2137 --$day; 2138 $match[3] -= 1970; 2139 $year -= 1970; 2140 } 2141 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], false), 2142 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, false), false); 2143 break; 2144 2145 case self::TIMESTAMP: 2146 if (is_numeric($date)) { 2147 return $this->_assign($calc, $date, $this->getUnixTimestamp()); 2148 } 2149 2150 // require_once 'Zend/Date/Exception.php'; 2151 throw new Zend_Date_Exception("invalid date ($date) operand, timestamp expected", 0, null, $date); 2152 break; 2153 2154 // additional formats 2155 // break intentionally omitted 2156 case self::ERA: 2157 case self::ERA_NAME: 2158 // require_once 'Zend/Date/Exception.php'; 2159 throw new Zend_Date_Exception('era not supported', 0, null, $date); 2160 break; 2161 2162 case self::DATES: 2163 try { 2164 $parsed = Zend_Locale_Format::getDate($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true)); 2165 2166 if (($calc == 'set') || ($calc == 'cmp')) { 2167 --$parsed['month']; 2168 --$month; 2169 --$parsed['day']; 2170 --$day; 2171 $parsed['year'] -= 1970; 2172 $year -= 1970; 2173 } 2174 2175 return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2176 $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2177 } catch (Zend_Locale_Exception $e) { 2178 // require_once 'Zend/Date/Exception.php'; 2179 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2180 } 2181 break; 2182 2183 case self::DATE_FULL: 2184 try { 2185 $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'full')); 2186 $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2187 2188 if (($calc == 'set') || ($calc == 'cmp')) { 2189 --$parsed['month']; 2190 --$month; 2191 --$parsed['day']; 2192 --$day; 2193 $parsed['year'] -= 1970; 2194 $year -= 1970; 2195 } 2196 return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2197 $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2198 } catch (Zend_Locale_Exception $e) { 2199 // require_once 'Zend/Date/Exception.php'; 2200 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2201 } 2202 break; 2203 2204 case self::DATE_LONG: 2205 try { 2206 $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'long')); 2207 $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2208 2209 if (($calc == 'set') || ($calc == 'cmp')){ 2210 --$parsed['month']; 2211 --$month; 2212 --$parsed['day']; 2213 --$day; 2214 $parsed['year'] -= 1970; 2215 $year -= 1970; 2216 } 2217 return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2218 $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2219 } catch (Zend_Locale_Exception $e) { 2220 // require_once 'Zend/Date/Exception.php'; 2221 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2222 } 2223 break; 2224 2225 case self::DATE_MEDIUM: 2226 try { 2227 $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'medium')); 2228 $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2229 2230 if (($calc == 'set') || ($calc == 'cmp')) { 2231 --$parsed['month']; 2232 --$month; 2233 --$parsed['day']; 2234 --$day; 2235 $parsed['year'] -= 1970; 2236 $year -= 1970; 2237 } 2238 return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2239 $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2240 } catch (Zend_Locale_Exception $e) { 2241 // require_once 'Zend/Date/Exception.php'; 2242 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2243 } 2244 break; 2245 2246 case self::DATE_SHORT: 2247 try { 2248 $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'short')); 2249 $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2250 2251 $parsed['year'] = self::getFullYear($parsed['year']); 2252 2253 if (($calc == 'set') || ($calc == 'cmp')) { 2254 --$parsed['month']; 2255 --$month; 2256 --$parsed['day']; 2257 --$day; 2258 $parsed['year'] -= 1970; 2259 $year -= 1970; 2260 } 2261 return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2262 $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2263 } catch (Zend_Locale_Exception $e) { 2264 // require_once 'Zend/Date/Exception.php'; 2265 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2266 } 2267 break; 2268 2269 case self::TIMES: 2270 try { 2271 if ($calc != 'set') { 2272 $month = 1; 2273 $day = 1; 2274 $year = 1970; 2275 } 2276 $parsed = Zend_Locale_Format::getTime($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true)); 2277 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), 2278 $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); 2279 } catch (Zend_Locale_Exception $e) { 2280 // require_once 'Zend/Date/Exception.php'; 2281 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2282 } 2283 break; 2284 2285 case self::TIME_FULL: 2286 try { 2287 $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'full')); 2288 $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2289 if ($calc != 'set') { 2290 $month = 1; 2291 $day = 1; 2292 $year = 1970; 2293 } 2294 2295 if (!isset($parsed['second'])) { 2296 $parsed['second'] = 0; 2297 } 2298 2299 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), 2300 $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); 2301 } catch (Zend_Locale_Exception $e) { 2302 // require_once 'Zend/Date/Exception.php'; 2303 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2304 } 2305 break; 2306 2307 case self::TIME_LONG: 2308 try { 2309 $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'long')); 2310 $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2311 if ($calc != 'set') { 2312 $month = 1; 2313 $day = 1; 2314 $year = 1970; 2315 } 2316 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), 2317 $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); 2318 } catch (Zend_Locale_Exception $e) { 2319 // require_once 'Zend/Date/Exception.php'; 2320 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2321 } 2322 break; 2323 2324 case self::TIME_MEDIUM: 2325 try { 2326 $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'medium')); 2327 $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2328 if ($calc != 'set') { 2329 $month = 1; 2330 $day = 1; 2331 $year = 1970; 2332 } 2333 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), 2334 $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); 2335 } catch (Zend_Locale_Exception $e) { 2336 // require_once 'Zend/Date/Exception.php'; 2337 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2338 } 2339 break; 2340 2341 case self::TIME_SHORT: 2342 try { 2343 $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'short')); 2344 $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2345 if ($calc != 'set') { 2346 $month = 1; 2347 $day = 1; 2348 $year = 1970; 2349 } 2350 2351 if (!isset($parsed['second'])) { 2352 $parsed['second'] = 0; 2353 } 2354 2355 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), 2356 $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); 2357 } catch (Zend_Locale_Exception $e) { 2358 // require_once 'Zend/Date/Exception.php'; 2359 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2360 } 2361 break; 2362 2363 case self::DATETIME: 2364 try { 2365 $parsed = Zend_Locale_Format::getDateTime($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true)); 2366 if (($calc == 'set') || ($calc == 'cmp')) { 2367 --$parsed['month']; 2368 --$month; 2369 --$parsed['day']; 2370 --$day; 2371 $parsed['year'] -= 1970; 2372 $year -= 1970; 2373 } 2374 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2375 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2376 } catch (Zend_Locale_Exception $e) { 2377 // require_once 'Zend/Date/Exception.php'; 2378 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2379 } 2380 break; 2381 2382 case self::DATETIME_FULL: 2383 try { 2384 $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'full')); 2385 $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2386 2387 if (($calc == 'set') || ($calc == 'cmp')) { 2388 --$parsed['month']; 2389 --$month; 2390 --$parsed['day']; 2391 --$day; 2392 $parsed['year'] -= 1970; 2393 $year -= 1970; 2394 } 2395 2396 if (!isset($parsed['second'])) { 2397 $parsed['second'] = 0; 2398 } 2399 2400 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2401 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2402 } catch (Zend_Locale_Exception $e) { 2403 // require_once 'Zend/Date/Exception.php'; 2404 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2405 } 2406 break; 2407 2408 case self::DATETIME_LONG: 2409 try { 2410 $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'long')); 2411 $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2412 2413 if (($calc == 'set') || ($calc == 'cmp')){ 2414 --$parsed['month']; 2415 --$month; 2416 --$parsed['day']; 2417 --$day; 2418 $parsed['year'] -= 1970; 2419 $year -= 1970; 2420 } 2421 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2422 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2423 } catch (Zend_Locale_Exception $e) { 2424 // require_once 'Zend/Date/Exception.php'; 2425 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2426 } 2427 break; 2428 2429 case self::DATETIME_MEDIUM: 2430 try { 2431 $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'medium')); 2432 $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2433 if (($calc == 'set') || ($calc == 'cmp')) { 2434 --$parsed['month']; 2435 --$month; 2436 --$parsed['day']; 2437 --$day; 2438 $parsed['year'] -= 1970; 2439 $year -= 1970; 2440 } 2441 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2442 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2443 } catch (Zend_Locale_Exception $e) { 2444 // require_once 'Zend/Date/Exception.php'; 2445 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2446 } 2447 break; 2448 2449 case self::DATETIME_SHORT: 2450 try { 2451 $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'short')); 2452 $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2453 2454 $parsed['year'] = self::getFullYear($parsed['year']); 2455 2456 if (($calc == 'set') || ($calc == 'cmp')) { 2457 --$parsed['month']; 2458 --$month; 2459 --$parsed['day']; 2460 --$day; 2461 $parsed['year'] -= 1970; 2462 $year -= 1970; 2463 } 2464 2465 if (!isset($parsed['second'])) { 2466 $parsed['second'] = 0; 2467 } 2468 2469 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2470 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2471 } catch (Zend_Locale_Exception $e) { 2472 // require_once 'Zend/Date/Exception.php'; 2473 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2474 } 2475 break; 2476 2477 // ATOM and RFC_3339 are identical 2478 case self::ATOM: 2479 case self::RFC_3339: 2480 $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); 2481 if (!$result) { 2482 // require_once 'Zend/Date/Exception.php'; 2483 throw new Zend_Date_Exception("invalid date ($date) operand, ATOM format expected", 0, null, $date); 2484 } 2485 2486 if (($calc == 'set') || ($calc == 'cmp')) { 2487 --$match[2]; 2488 --$month; 2489 --$match[3]; 2490 --$day; 2491 $match[1] -= 1970; 2492 $year -= 1970; 2493 } 2494 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $match[2], 1 + $match[3], 1970 + $match[1], true), 2495 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); 2496 break; 2497 2498 case self::COOKIE: 2499 $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); 2500 if (!$result) { 2501 // require_once 'Zend/Date/Exception.php'; 2502 throw new Zend_Date_Exception("invalid date ($date) operand, COOKIE format expected", 0, null, $date); 2503 } 2504 $matchStartPos = iconv_strpos($match[0], ' ', 0, 'UTF-8') + 1; 2505 $match[0] = iconv_substr($match[0], 2506 $matchStartPos, 2507 iconv_strlen($match[0], 'UTF-8') - $matchStartPos, 2508 'UTF-8'); 2509 2510 $months = $this->_getDigitFromName($match[2]); 2511 $match[3] = self::getFullYear($match[3]); 2512 2513 if (($calc == 'set') || ($calc == 'cmp')) { 2514 --$months; 2515 --$month; 2516 --$match[1]; 2517 --$day; 2518 $match[3] -= 1970; 2519 $year -= 1970; 2520 } 2521 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true), 2522 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); 2523 break; 2524 2525 case self::RFC_822: 2526 case self::RFC_1036: 2527 // new RFC 822 format, identical to RFC 1036 standard 2528 $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); 2529 if (!$result) { 2530 // require_once 'Zend/Date/Exception.php'; 2531 throw new Zend_Date_Exception("invalid date ($date) operand, RFC 822 date format expected", 0, null, $date); 2532 } 2533 2534 $months = $this->_getDigitFromName($match[2]); 2535 $match[3] = self::getFullYear($match[3]); 2536 2537 if (($calc == 'set') || ($calc == 'cmp')) { 2538 --$months; 2539 --$month; 2540 --$match[1]; 2541 --$day; 2542 $match[3] -= 1970; 2543 $year -= 1970; 2544 } 2545 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], false), 2546 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, false), false); 2547 break; 2548 2549 case self::RFC_850: 2550 $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); 2551 if (!$result) { 2552 // require_once 'Zend/Date/Exception.php'; 2553 throw new Zend_Date_Exception("invalid date ($date) operand, RFC 850 date format expected", 0, null, $date); 2554 } 2555 2556 $months = $this->_getDigitFromName($match[2]); 2557 $match[3] = self::getFullYear($match[3]); 2558 2559 if (($calc == 'set') || ($calc == 'cmp')) { 2560 --$months; 2561 --$month; 2562 --$match[1]; 2563 --$day; 2564 $match[3] -= 1970; 2565 $year -= 1970; 2566 } 2567 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true), 2568 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); 2569 break; 2570 2571 case self::RFC_1123: 2572 $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); 2573 if (!$result) { 2574 // require_once 'Zend/Date/Exception.php'; 2575 throw new Zend_Date_Exception("invalid date ($date) operand, RFC 1123 date format expected", 0, null, $date); 2576 } 2577 2578 $months = $this->_getDigitFromName($match[2]); 2579 2580 if (($calc == 'set') || ($calc == 'cmp')) { 2581 --$months; 2582 --$month; 2583 --$match[1]; 2584 --$day; 2585 $match[3] -= 1970; 2586 $year -= 1970; 2587 } 2588 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true), 2589 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); 2590 break; 2591 2592 case self::RSS: 2593 $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); 2594 if (!$result) { 2595 // require_once 'Zend/Date/Exception.php'; 2596 throw new Zend_Date_Exception("invalid date ($date) operand, RSS date format expected", 0, null, $date); 2597 } 2598 2599 $months = $this->_getDigitFromName($match[2]); 2600 $match[3] = self::getFullYear($match[3]); 2601 2602 if (($calc == 'set') || ($calc == 'cmp')) { 2603 --$months; 2604 --$month; 2605 --$match[1]; 2606 --$day; 2607 $match[3] -= 1970; 2608 $year -= 1970; 2609 } 2610 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true), 2611 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); 2612 break; 2613 2614 case self::W3C: 2615 $result = preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})[+-]{1}\d{2}:\d{2}$/', $date, $match); 2616 if (!$result) { 2617 // require_once 'Zend/Date/Exception.php'; 2618 throw new Zend_Date_Exception("invalid date ($date) operand, W3C date format expected", 0, null, $date); 2619 } 2620 2621 if (($calc == 'set') || ($calc == 'cmp')) { 2622 --$match[2]; 2623 --$month; 2624 --$match[3]; 2625 --$day; 2626 $match[1] -= 1970; 2627 $year -= 1970; 2628 } 2629 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $match[2], 1 + $match[3], 1970 + $match[1], true), 2630 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); 2631 break; 2632 2633 default: 2634 if (!is_numeric($date) || !empty($part)) { 2635 try { 2636 if (empty($part)) { 2637 $part = Zend_Locale_Format::getDateFormat($locale) . " "; 2638 $part .= Zend_Locale_Format::getTimeFormat($locale); 2639 } 2640 2641 $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $part, 'locale' => $locale, 'fix_date' => true, 'format_type' => 'iso')); 2642 if ((strpos(strtoupper($part), 'YY') !== false) and (strpos(strtoupper($part), 'YYYY') === false)) { 2643 $parsed['year'] = self::getFullYear($parsed['year']); 2644 } 2645 2646 if (($calc == 'set') || ($calc == 'cmp')) { 2647 if (isset($parsed['month'])) { 2648 --$parsed['month']; 2649 } else { 2650 $parsed['month'] = 0; 2651 } 2652 2653 if (isset($parsed['day'])) { 2654 --$parsed['day']; 2655 } else { 2656 $parsed['day'] = 0; 2657 } 2658 2659 if (!isset($parsed['year'])) { 2660 $parsed['year'] = 1970; 2661 } 2662 } 2663 2664 return $this->_assign($calc, $this->mktime( 2665 isset($parsed['hour']) ? $parsed['hour'] : 0, 2666 isset($parsed['minute']) ? $parsed['minute'] : 0, 2667 isset($parsed['second']) ? $parsed['second'] : 0, 2668 isset($parsed['month']) ? (1 + $parsed['month']) : 1, 2669 isset($parsed['day']) ? (1 + $parsed['day']) : 1, 2670 $parsed['year'], 2671 false), $this->getUnixTimestamp(), false); 2672 } catch (Zend_Locale_Exception $e) { 2673 if (!is_numeric($date)) { 2674 // require_once 'Zend/Date/Exception.php'; 2675 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2676 } 2677 } 2678 } 2679 2680 return $this->_assign($calc, $date, $this->getUnixTimestamp(), false); 2681 break; 2682 } 2683 } 2684 2685 /** 2686 * Returns true when both date objects or date parts are equal. 2687 * For example: 2688 * 15.May.2000 <-> 15.June.2000 Equals only for Day or Year... all other will return false 2689 * 2690 * @param string|integer|array|Zend_Date $date Date or datepart to equal with 2691 * @param string $part OPTIONAL Part of the date to compare, if null the timestamp is used 2692 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2693 * @return boolean 2694 * @throws Zend_Date_Exception 2695 */ 2696 public function equals($date, $part = self::TIMESTAMP, $locale = null) 2697 { 2698 $result = $this->compare($date, $part, $locale); 2699 2700 if ($result == 0) { 2701 return true; 2702 } 2703 2704 return false; 2705 } 2706 2707 /** 2708 * Returns if the given date or datepart is earlier 2709 * For example: 2710 * 15.May.2000 <-> 13.June.1999 will return true for day, year and date, but not for month 2711 * 2712 * @param string|integer|array|Zend_Date $date Date or datepart to compare with 2713 * @param string $part OPTIONAL Part of the date to compare, if null the timestamp is used 2714 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2715 * @return boolean 2716 * @throws Zend_Date_Exception 2717 */ 2718 public function isEarlier($date, $part = null, $locale = null) 2719 { 2720 $result = $this->compare($date, $part, $locale); 2721 2722 if ($result == -1) { 2723 return true; 2724 } 2725 2726 return false; 2727 } 2728 2729 /** 2730 * Returns if the given date or datepart is later 2731 * For example: 2732 * 15.May.2000 <-> 13.June.1999 will return true for month but false for day, year and date 2733 * Returns if the given date is later 2734 * 2735 * @param string|integer|array|Zend_Date $date Date or datepart to compare with 2736 * @param string $part OPTIONAL Part of the date to compare, if null the timestamp is used 2737 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2738 * @return boolean 2739 * @throws Zend_Date_Exception 2740 */ 2741 public function isLater($date, $part = null, $locale = null) 2742 { 2743 $result = $this->compare($date, $part, $locale); 2744 2745 if ($result == 1) { 2746 return true; 2747 } 2748 2749 return false; 2750 } 2751 2752 /** 2753 * Returns only the time of the date as new Zend_Date object 2754 * For example: 2755 * 15.May.2000 10:11:23 will return a dateobject equal to 01.Jan.1970 10:11:23 2756 * 2757 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2758 * @return Zend_Date 2759 */ 2760 public function getTime($locale = null) 2761 { 2762 if (self::$_options['format_type'] == 'php') { 2763 $format = 'H:i:s'; 2764 } else { 2765 $format = self::TIME_MEDIUM; 2766 } 2767 2768 return $this->copyPart($format, $locale); 2769 } 2770 2771 /** 2772 * Returns the calculated time 2773 * 2774 * @param string $calc Calculation to make 2775 * @param string|integer|array|Zend_Date $time Time to calculate with, if null the actual time is taken 2776 * @param string $format Timeformat for parsing input 2777 * @param string|Zend_Locale $locale Locale for parsing input 2778 * @return integer|Zend_Date new time 2779 * @throws Zend_Date_Exception 2780 */ 2781 private function _time($calc, $time, $format, $locale) 2782 { 2783 if ($time === null) { 2784 // require_once 'Zend/Date/Exception.php'; 2785 throw new Zend_Date_Exception('parameter $time must be set, null is not allowed'); 2786 } 2787 2788 if ($time instanceof Zend_Date) { 2789 // extract time from object 2790 $time = $time->toString('HH:mm:ss', 'iso'); 2791 } else { 2792 if (is_array($time)) { 2793 if ((isset($time['hour']) === true) or (isset($time['minute']) === true) or 2794 (isset($time['second']) === true)) { 2795 $parsed = $time; 2796 } else { 2797 // require_once 'Zend/Date/Exception.php'; 2798 throw new Zend_Date_Exception("no hour, minute or second given in array"); 2799 } 2800 } else { 2801 if (self::$_options['format_type'] == 'php') { 2802 $format = Zend_Locale_Format::convertPhpToIsoFormat($format); 2803 } 2804 try { 2805 if ($locale === null) { 2806 $locale = $this->getLocale(); 2807 } 2808 2809 $parsed = Zend_Locale_Format::getTime($time, array('date_format' => $format, 'locale' => $locale, 'format_type' => 'iso')); 2810 } catch (Zend_Locale_Exception $e) { 2811 // require_once 'Zend/Date/Exception.php'; 2812 throw new Zend_Date_Exception($e->getMessage(), 0, $e); 2813 } 2814 } 2815 2816 if (!array_key_exists('hour', $parsed)) { 2817 $parsed['hour'] = 0; 2818 } 2819 2820 if (!array_key_exists('minute', $parsed)) { 2821 $parsed['minute'] = 0; 2822 } 2823 2824 if (!array_key_exists('second', $parsed)) { 2825 $parsed['second'] = 0; 2826 } 2827 2828 $time = str_pad($parsed['hour'], 2, '0', STR_PAD_LEFT) . ":"; 2829 $time .= str_pad($parsed['minute'], 2, '0', STR_PAD_LEFT) . ":"; 2830 $time .= str_pad($parsed['second'], 2, '0', STR_PAD_LEFT); 2831 } 2832 2833 $return = $this->_calcdetail($calc, $time, self::TIMES, 'de'); 2834 if ($calc != 'cmp') { 2835 return $this; 2836 } 2837 2838 return $return; 2839 } 2840 2841 2842 /** 2843 * Sets a new time for the date object. Format defines how to parse the time string. 2844 * Also a complete date can be given, but only the time is used for setting. 2845 * For example: dd.MMMM.yyTHH:mm' and 'ss sec'-> 10.May.07T25:11 and 44 sec => 1h11min44sec + 1 day 2846 * Returned is the new date object and the existing date is left as it was before 2847 * 2848 * @param string|integer|array|Zend_Date $time Time to set 2849 * @param string $format OPTIONAL Timeformat for parsing input 2850 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2851 * @return Zend_Date Provides a fluent interface 2852 * @throws Zend_Date_Exception 2853 */ 2854 public function setTime($time, $format = null, $locale = null) 2855 { 2856 return $this->_time('set', $time, $format, $locale); 2857 } 2858 2859 2860 /** 2861 * Adds a time to the existing date. Format defines how to parse the time string. 2862 * If only parts are given the other parts are set to 0. 2863 * If no format is given, the standardformat of this locale is used. 2864 * For example: HH:mm:ss -> 10 -> +10 hours 2865 * 2866 * @param string|integer|array|Zend_Date $time Time to add 2867 * @param string $format OPTIONAL Timeformat for parsing input 2868 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2869 * @return Zend_Date Provides a fluent interface 2870 * @throws Zend_Date_Exception 2871 */ 2872 public function addTime($time, $format = null, $locale = null) 2873 { 2874 return $this->_time('add', $time, $format, $locale); 2875 } 2876 2877 2878 /** 2879 * Subtracts a time from the existing date. Format defines how to parse the time string. 2880 * If only parts are given the other parts are set to 0. 2881 * If no format is given, the standardformat of this locale is used. 2882 * For example: HH:mm:ss -> 10 -> -10 hours 2883 * 2884 * @param string|integer|array|Zend_Date $time Time to sub 2885 * @param string $format OPTIONAL Timeformat for parsing input 2886 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2887 * @return Zend_Date Provides a fluent inteface 2888 * @throws Zend_Date_Exception 2889 */ 2890 public function subTime($time, $format = null, $locale = null) 2891 { 2892 return $this->_time('sub', $time, $format, $locale); 2893 } 2894 2895 2896 /** 2897 * Compares the time from the existing date. Format defines how to parse the time string. 2898 * If only parts are given the other parts are set to default. 2899 * If no format us given, the standardformat of this locale is used. 2900 * For example: HH:mm:ss -> 10 -> 10 hours 2901 * 2902 * @param string|integer|array|Zend_Date $time Time to compare 2903 * @param string $format OPTIONAL Timeformat for parsing input 2904 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2905 * @return integer 0 = equal, 1 = later, -1 = earlier 2906 * @throws Zend_Date_Exception 2907 */ 2908 public function compareTime($time, $format = null, $locale = null) 2909 { 2910 return $this->_time('cmp', $time, $format, $locale); 2911 } 2912 2913 /** 2914 * Returns a clone of $this, with the time part set to 00:00:00. 2915 * 2916 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2917 * @return Zend_Date 2918 */ 2919 public function getDate($locale = null) 2920 { 2921 $orig = self::$_options['format_type']; 2922 if (self::$_options['format_type'] == 'php') { 2923 self::$_options['format_type'] = 'iso'; 2924 } 2925 2926 $date = $this->copyPart(self::DATE_MEDIUM, $locale); 2927 $date->addTimestamp($this->getGmtOffset()); 2928 self::$_options['format_type'] = $orig; 2929 2930 return $date; 2931 } 2932 2933 /** 2934 * Returns the calculated date 2935 * 2936 * @param string $calc Calculation to make 2937 * @param string|integer|array|Zend_Date $date Date to calculate with, if null the actual date is taken 2938 * @param string $format Date format for parsing 2939 * @param string|Zend_Locale $locale Locale for parsing input 2940 * @return integer|Zend_Date new date 2941 * @throws Zend_Date_Exception 2942 */ 2943 private function _date($calc, $date, $format, $locale) 2944 { 2945 if ($date === null) { 2946 // require_once 'Zend/Date/Exception.php'; 2947 throw new Zend_Date_Exception('parameter $date must be set, null is not allowed'); 2948 } 2949 2950 if ($date instanceof Zend_Date) { 2951 // extract date from object 2952 $date = $date->toString('d.M.y', 'iso'); 2953 } else { 2954 if (is_array($date)) { 2955 if ((isset($date['year']) === true) or (isset($date['month']) === true) or 2956 (isset($date['day']) === true)) { 2957 $parsed = $date; 2958 } else { 2959 // require_once 'Zend/Date/Exception.php'; 2960 throw new Zend_Date_Exception("no day,month or year given in array"); 2961 } 2962 } else { 2963 if ((self::$_options['format_type'] == 'php') && !defined($format)) { 2964 $format = Zend_Locale_Format::convertPhpToIsoFormat($format); 2965 } 2966 try { 2967 if ($locale === null) { 2968 $locale = $this->getLocale(); 2969 } 2970 2971 $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'locale' => $locale, 'format_type' => 'iso')); 2972 if ((strpos(strtoupper($format), 'YY') !== false) and (strpos(strtoupper($format), 'YYYY') === false)) { 2973 $parsed['year'] = self::getFullYear($parsed['year']); 2974 } 2975 } catch (Zend_Locale_Exception $e) { 2976 // require_once 'Zend/Date/Exception.php'; 2977 throw new Zend_Date_Exception($e->getMessage(), 0, $e); 2978 } 2979 } 2980 2981 if (!array_key_exists('day', $parsed)) { 2982 $parsed['day'] = 1; 2983 } 2984 2985 if (!array_key_exists('month', $parsed)) { 2986 $parsed['month'] = 1; 2987 } 2988 2989 if (!array_key_exists('year', $parsed)) { 2990 $parsed['year'] = 0; 2991 } 2992 2993 $date = $parsed['day'] . "." . $parsed['month'] . "." . $parsed['year']; 2994 } 2995 2996 $return = $this->_calcdetail($calc, $date, self::DATE_MEDIUM, 'de'); 2997 if ($calc != 'cmp') { 2998 return $this; 2999 } 3000 return $return; 3001 } 3002 3003 3004 /** 3005 * Sets a new date for the date object. Format defines how to parse the date string. 3006 * Also a complete date with time can be given, but only the date is used for setting. 3007 * For example: MMMM.yy HH:mm-> May.07 22:11 => 01.May.07 00:00 3008 * Returned is the new date object and the existing time is left as it was before 3009 * 3010 * @param string|integer|array|Zend_Date $date Date to set 3011 * @param string $format OPTIONAL Date format for parsing 3012 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3013 * @return Zend_Date Provides a fluent interface 3014 * @throws Zend_Date_Exception 3015 */ 3016 public function setDate($date, $format = null, $locale = null) 3017 { 3018 return $this->_date('set', $date, $format, $locale); 3019 } 3020 3021 3022 /** 3023 * Adds a date to the existing date object. Format defines how to parse the date string. 3024 * If only parts are given the other parts are set to 0. 3025 * If no format is given, the standardformat of this locale is used. 3026 * For example: MM.dd.YYYY -> 10 -> +10 months 3027 * 3028 * @param string|integer|array|Zend_Date $date Date to add 3029 * @param string $format OPTIONAL Date format for parsing input 3030 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3031 * @return Zend_Date Provides a fluent interface 3032 * @throws Zend_Date_Exception 3033 */ 3034 public function addDate($date, $format = null, $locale = null) 3035 { 3036 return $this->_date('add', $date, $format, $locale); 3037 } 3038 3039 3040 /** 3041 * Subtracts a date from the existing date object. Format defines how to parse the date string. 3042 * If only parts are given the other parts are set to 0. 3043 * If no format is given, the standardformat of this locale is used. 3044 * For example: MM.dd.YYYY -> 10 -> -10 months 3045 * Be aware: Subtracting 2 months is not equal to Adding -2 months !!! 3046 * 3047 * @param string|integer|array|Zend_Date $date Date to sub 3048 * @param string $format OPTIONAL Date format for parsing input 3049 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3050 * @return Zend_Date Provides a fluent interface 3051 * @throws Zend_Date_Exception 3052 */ 3053 public function subDate($date, $format = null, $locale = null) 3054 { 3055 return $this->_date('sub', $date, $format, $locale); 3056 } 3057 3058 3059 /** 3060 * Compares the date from the existing date object, ignoring the time. 3061 * Format defines how to parse the date string. 3062 * If only parts are given the other parts are set to 0. 3063 * If no format is given, the standardformat of this locale is used. 3064 * For example: 10.01.2000 => 10.02.1999 -> false 3065 * 3066 * @param string|integer|array|Zend_Date $date Date to compare 3067 * @param string $format OPTIONAL Date format for parsing input 3068 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3069 * @return integer 0 = equal, 1 = later, -1 = earlier 3070 * @throws Zend_Date_Exception 3071 */ 3072 public function compareDate($date, $format = null, $locale = null) 3073 { 3074 return $this->_date('cmp', $date, $format, $locale); 3075 } 3076 3077 3078 /** 3079 * Returns the full ISO 8601 date from the date object. 3080 * Always the complete ISO 8601 specifiction is used. If an other ISO date is needed 3081 * (ISO 8601 defines several formats) use toString() instead. 3082 * This function does not return the ISO date as object. Use copy() instead. 3083 * 3084 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3085 * @return string 3086 */ 3087 public function getIso($locale = null) 3088 { 3089 return $this->toString(self::ISO_8601, 'iso', $locale); 3090 } 3091 3092 3093 /** 3094 * Sets a new date for the date object. Not given parts are set to default. 3095 * Only supported ISO 8601 formats are accepted. 3096 * For example: 050901 -> 01.Sept.2005 00:00:00, 20050201T10:00:30 -> 01.Feb.2005 10h00m30s 3097 * Returned is the new date object 3098 * 3099 * @param string|integer|Zend_Date $date ISO Date to set 3100 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3101 * @return Zend_Date Provides a fluent interface 3102 * @throws Zend_Date_Exception 3103 */ 3104 public function setIso($date, $locale = null) 3105 { 3106 return $this->_calcvalue('set', $date, 'iso', self::ISO_8601, $locale); 3107 } 3108 3109 3110 /** 3111 * Adds a ISO date to the date object. Not given parts are set to default. 3112 * Only supported ISO 8601 formats are accepted. 3113 * For example: 050901 -> + 01.Sept.2005 00:00:00, 10:00:00 -> +10h 3114 * Returned is the new date object 3115 * 3116 * @param string|integer|Zend_Date $date ISO Date to add 3117 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3118 * @return Zend_Date Provides a fluent interface 3119 * @throws Zend_Date_Exception 3120 */ 3121 public function addIso($date, $locale = null) 3122 { 3123 return $this->_calcvalue('add', $date, 'iso', self::ISO_8601, $locale); 3124 } 3125 3126 3127 /** 3128 * Subtracts a ISO date from the date object. Not given parts are set to default. 3129 * Only supported ISO 8601 formats are accepted. 3130 * For example: 050901 -> - 01.Sept.2005 00:00:00, 10:00:00 -> -10h 3131 * Returned is the new date object 3132 * 3133 * @param string|integer|Zend_Date $date ISO Date to sub 3134 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3135 * @return Zend_Date Provides a fluent interface 3136 * @throws Zend_Date_Exception 3137 */ 3138 public function subIso($date, $locale = null) 3139 { 3140 return $this->_calcvalue('sub', $date, 'iso', self::ISO_8601, $locale); 3141 } 3142 3143 3144 /** 3145 * Compares a ISO date with the date object. Not given parts are set to default. 3146 * Only supported ISO 8601 formats are accepted. 3147 * For example: 050901 -> - 01.Sept.2005 00:00:00, 10:00:00 -> -10h 3148 * Returns if equal, earlier or later 3149 * 3150 * @param string|integer|Zend_Date $date ISO Date to sub 3151 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3152 * @return integer 0 = equal, 1 = later, -1 = earlier 3153 * @throws Zend_Date_Exception 3154 */ 3155 public function compareIso($date, $locale = null) 3156 { 3157 return $this->_calcvalue('cmp', $date, 'iso', self::ISO_8601, $locale); 3158 } 3159 3160 3161 /** 3162 * Returns a RFC 822 compilant datestring from the date object. 3163 * This function does not return the RFC date as object. Use copy() instead. 3164 * 3165 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3166 * @return string 3167 */ 3168 public function getArpa($locale = null) 3169 { 3170 if (self::$_options['format_type'] == 'php') { 3171 $format = 'D\, d M y H\:i\:s O'; 3172 } else { 3173 $format = self::RFC_822; 3174 } 3175 3176 return $this->toString($format, 'iso', $locale); 3177 } 3178 3179 3180 /** 3181 * Sets a RFC 822 date as new date for the date object. 3182 * Only RFC 822 compilant date strings are accepted. 3183 * For example: Sat, 14 Feb 09 00:31:30 +0100 3184 * Returned is the new date object 3185 * 3186 * @param string|integer|Zend_Date $date RFC 822 to set 3187 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3188 * @return Zend_Date Provides a fluent interface 3189 * @throws Zend_Date_Exception 3190 */ 3191 public function setArpa($date, $locale = null) 3192 { 3193 return $this->_calcvalue('set', $date, 'arpa', self::RFC_822, $locale); 3194 } 3195 3196 3197 /** 3198 * Adds a RFC 822 date to the date object. 3199 * ARPA messages are used in emails or HTTP Headers. 3200 * Only RFC 822 compilant date strings are accepted. 3201 * For example: Sat, 14 Feb 09 00:31:30 +0100 3202 * Returned is the new date object 3203 * 3204 * @param string|integer|Zend_Date $date RFC 822 Date to add 3205 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3206 * @return Zend_Date Provides a fluent interface 3207 * @throws Zend_Date_Exception 3208 */ 3209 public function addArpa($date, $locale = null) 3210 { 3211 return $this->_calcvalue('add', $date, 'arpa', self::RFC_822, $locale); 3212 } 3213 3214 3215 /** 3216 * Subtracts a RFC 822 date from the date object. 3217 * ARPA messages are used in emails or HTTP Headers. 3218 * Only RFC 822 compilant date strings are accepted. 3219 * For example: Sat, 14 Feb 09 00:31:30 +0100 3220 * Returned is the new date object 3221 * 3222 * @param string|integer|Zend_Date $date RFC 822 Date to sub 3223 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3224 * @return Zend_Date Provides a fluent interface 3225 * @throws Zend_Date_Exception 3226 */ 3227 public function subArpa($date, $locale = null) 3228 { 3229 return $this->_calcvalue('sub', $date, 'arpa', self::RFC_822, $locale); 3230 } 3231 3232 3233 /** 3234 * Compares a RFC 822 compilant date with the date object. 3235 * ARPA messages are used in emails or HTTP Headers. 3236 * Only RFC 822 compilant date strings are accepted. 3237 * For example: Sat, 14 Feb 09 00:31:30 +0100 3238 * Returns if equal, earlier or later 3239 * 3240 * @param string|integer|Zend_Date $date RFC 822 Date to sub 3241 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3242 * @return integer 0 = equal, 1 = later, -1 = earlier 3243 * @throws Zend_Date_Exception 3244 */ 3245 public function compareArpa($date, $locale = null) 3246 { 3247 return $this->_calcvalue('cmp', $date, 'arpa', self::RFC_822, $locale); 3248 } 3249 3250 /** 3251 * Check if location is supported 3252 * 3253 * @param array $location locations array 3254 * @throws Zend_Date_Exception 3255 * @return float $horizon float 3256 */ 3257 private function _checkLocation($location) 3258 { 3259 if (!isset($location['longitude']) or !isset($location['latitude'])) { 3260 // require_once 'Zend/Date/Exception.php'; 3261 throw new Zend_Date_Exception('Location must include \'longitude\' and \'latitude\'', 0, null, $location); 3262 } 3263 if (($location['longitude'] > 180) or ($location['longitude'] < -180)) { 3264 // require_once 'Zend/Date/Exception.php'; 3265 throw new Zend_Date_Exception('Longitude must be between -180 and 180', 0, null, $location); 3266 } 3267 if (($location['latitude'] > 90) or ($location['latitude'] < -90)) { 3268 // require_once 'Zend/Date/Exception.php'; 3269 throw new Zend_Date_Exception('Latitude must be between -90 and 90', 0, null, $location); 3270 } 3271 3272 if (!isset($location['horizon'])){ 3273 $location['horizon'] = 'effective'; 3274 } 3275 3276 switch ($location['horizon']) { 3277 case 'civil' : 3278 return -0.104528; 3279 break; 3280 case 'nautic' : 3281 return -0.207912; 3282 break; 3283 case 'astronomic' : 3284 return -0.309017; 3285 break; 3286 default : 3287 return -0.0145439; 3288 break; 3289 } 3290 } 3291 3292 3293 /** 3294 * Returns the time of sunrise for this date and a given location as new date object 3295 * For a list of cities and correct locations use the class Zend_Date_Cities 3296 * 3297 * @param array $location location of sunrise 3298 * ['horizon'] -> civil, nautic, astronomical, effective (default) 3299 * ['longitude'] -> longitude of location 3300 * ['latitude'] -> latitude of location 3301 * @return Zend_Date 3302 * @throws Zend_Date_Exception 3303 */ 3304 public function getSunrise($location) 3305 { 3306 $horizon = $this->_checkLocation($location); 3307 $result = clone $this; 3308 $result->set($this->calcSun($location, $horizon, true), self::TIMESTAMP); 3309 return $result; 3310 } 3311 3312 3313 /** 3314 * Returns the time of sunset for this date and a given location as new date object 3315 * For a list of cities and correct locations use the class Zend_Date_Cities 3316 * 3317 * @param array $location location of sunset 3318 * ['horizon'] -> civil, nautic, astronomical, effective (default) 3319 * ['longitude'] -> longitude of location 3320 * ['latitude'] -> latitude of location 3321 * @return Zend_Date 3322 * @throws Zend_Date_Exception 3323 */ 3324 public function getSunset($location) 3325 { 3326 $horizon = $this->_checkLocation($location); 3327 $result = clone $this; 3328 $result->set($this->calcSun($location, $horizon, false), self::TIMESTAMP); 3329 return $result; 3330 } 3331 3332 3333 /** 3334 * Returns an array with the sunset and sunrise dates for all horizon types 3335 * For a list of cities and correct locations use the class Zend_Date_Cities 3336 * 3337 * @param array $location location of suninfo 3338 * ['horizon'] -> civil, nautic, astronomical, effective (default) 3339 * ['longitude'] -> longitude of location 3340 * ['latitude'] -> latitude of location 3341 * @return array - [sunset|sunrise][effective|civil|nautic|astronomic] 3342 * @throws Zend_Date_Exception 3343 */ 3344 public function getSunInfo($location) 3345 { 3346 $suninfo = array(); 3347 for ($i = 0; $i < 4; ++$i) { 3348 switch ($i) { 3349 case 0 : 3350 $location['horizon'] = 'effective'; 3351 break; 3352 case 1 : 3353 $location['horizon'] = 'civil'; 3354 break; 3355 case 2 : 3356 $location['horizon'] = 'nautic'; 3357 break; 3358 case 3 : 3359 $location['horizon'] = 'astronomic'; 3360 break; 3361 } 3362 $horizon = $this->_checkLocation($location); 3363 $result = clone $this; 3364 $result->set($this->calcSun($location, $horizon, true), self::TIMESTAMP); 3365 $suninfo['sunrise'][$location['horizon']] = $result; 3366 $result = clone $this; 3367 $result->set($this->calcSun($location, $horizon, false), self::TIMESTAMP); 3368 $suninfo['sunset'][$location['horizon']] = $result; 3369 } 3370 return $suninfo; 3371 } 3372 3373 /** 3374 * Check a given year for leap year. 3375 * 3376 * @param integer|array|Zend_Date $year Year to check 3377 * @throws Zend_Date_Exception 3378 * @return boolean 3379 */ 3380 public static function checkLeapYear($year) 3381 { 3382 if ($year instanceof Zend_Date) { 3383 $year = (int) $year->toString(self::YEAR, 'iso'); 3384 } 3385 3386 if (is_array($year)) { 3387 if (isset($year['year']) === true) { 3388 $year = $year['year']; 3389 } else { 3390 // require_once 'Zend/Date/Exception.php'; 3391 throw new Zend_Date_Exception("no year given in array"); 3392 } 3393 } 3394 3395 if (!is_numeric($year)) { 3396 // require_once 'Zend/Date/Exception.php'; 3397 throw new Zend_Date_Exception("year ($year) has to be integer for checkLeapYear()", 0, null, $year); 3398 } 3399 3400 return (bool) parent::isYearLeapYear($year); 3401 } 3402 3403 3404 /** 3405 * Returns true, if the year is a leap year. 3406 * 3407 * @return boolean 3408 */ 3409 public function isLeapYear() 3410 { 3411 return self::checkLeapYear($this); 3412 } 3413 3414 3415 /** 3416 * Returns if the set date is todays date 3417 * 3418 * @return boolean 3419 */ 3420 public function isToday() 3421 { 3422 $today = $this->date('Ymd', $this->_getTime()); 3423 $day = $this->date('Ymd', $this->getUnixTimestamp()); 3424 return ($today == $day); 3425 } 3426 3427 3428 /** 3429 * Returns if the set date is yesterdays date 3430 * 3431 * @return boolean 3432 */ 3433 public function isYesterday() 3434 { 3435 list($year, $month, $day) = explode('-', $this->date('Y-m-d', $this->_getTime())); 3436 // adjusts for leap days and DST changes that are timezone specific 3437 $yesterday = $this->date('Ymd', $this->mktime(0, 0, 0, $month, $day -1, $year)); 3438 $day = $this->date('Ymd', $this->getUnixTimestamp()); 3439 return $day == $yesterday; 3440 } 3441 3442 3443 /** 3444 * Returns if the set date is tomorrows date 3445 * 3446 * @return boolean 3447 */ 3448 public function isTomorrow() 3449 { 3450 list($year, $month, $day) = explode('-', $this->date('Y-m-d', $this->_getTime())); 3451 // adjusts for leap days and DST changes that are timezone specific 3452 $tomorrow = $this->date('Ymd', $this->mktime(0, 0, 0, $month, $day +1, $year)); 3453 $day = $this->date('Ymd', $this->getUnixTimestamp()); 3454 return $day == $tomorrow; 3455 } 3456 3457 /** 3458 * Returns the actual date as new date object 3459 * 3460 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3461 * @return Zend_Date 3462 */ 3463 public static function now($locale = null) 3464 { 3465 return new Zend_Date(time(), self::TIMESTAMP, $locale); 3466 } 3467 3468 /** 3469 * Calculate date details 3470 * 3471 * @param string $calc Calculation to make 3472 * @param string|integer|array|Zend_Date $date Date or Part to calculate 3473 * @param string $type Datepart for Calculation 3474 * @param string|Zend_Locale $locale Locale for parsing input 3475 * @return integer|string new date 3476 * @throws Zend_Date_Exception 3477 */ 3478 private function _calcdetail($calc, $date, $type, $locale) 3479 { 3480 $old = false; 3481 if (self::$_options['format_type'] == 'php') { 3482 self::$_options['format_type'] = 'iso'; 3483 $old = true; 3484 } 3485 3486 switch($calc) { 3487 case 'set' : 3488 $return = $this->set($date, $type, $locale); 3489 break; 3490 case 'add' : 3491 $return = $this->add($date, $type, $locale); 3492 break; 3493 case 'sub' : 3494 $return = $this->sub($date, $type, $locale); 3495 break; 3496 default : 3497 $return = $this->compare($date, $type, $locale); 3498 break; 3499 } 3500 3501 if ($old) { 3502 self::$_options['format_type'] = 'php'; 3503 } 3504 3505 return $return; 3506 } 3507 3508 /** 3509 * Internal calculation, returns the requested date type 3510 * 3511 * @param string $calc Calculation to make 3512 * @param string|integer|Zend_Date $value Datevalue to calculate with, if null the actual value is taken 3513 * @param string $type 3514 * @param string $parameter 3515 * @param string|Zend_Locale $locale Locale for parsing input 3516 * @throws Zend_Date_Exception 3517 * @return integer|Zend_Date new date 3518 */ 3519 private function _calcvalue($calc, $value, $type, $parameter, $locale) 3520 { 3521 if ($value === null) { 3522 // require_once 'Zend/Date/Exception.php'; 3523 throw new Zend_Date_Exception("parameter $type must be set, null is not allowed"); 3524 } 3525 3526 if ($locale === null) { 3527 $locale = $this->getLocale(); 3528 } 3529 3530 if ($value instanceof Zend_Date) { 3531 // extract value from object 3532 $value = $value->toString($parameter, 'iso', $locale); 3533 } else if (!is_array($value) && !is_numeric($value) && ($type != 'iso') && ($type != 'arpa')) { 3534 // require_once 'Zend/Date/Exception.php'; 3535 throw new Zend_Date_Exception("invalid $type ($value) operand", 0, null, $value); 3536 } 3537 3538 $return = $this->_calcdetail($calc, $value, $parameter, $locale); 3539 if ($calc != 'cmp') { 3540 return $this; 3541 } 3542 return $return; 3543 } 3544 3545 3546 /** 3547 * Returns only the year from the date object as new object. 3548 * For example: 10.May.2000 10:30:00 -> 01.Jan.2000 00:00:00 3549 * 3550 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3551 * @return Zend_Date 3552 */ 3553 public function getYear($locale = null) 3554 { 3555 if (self::$_options['format_type'] == 'php') { 3556 $format = 'Y'; 3557 } else { 3558 $format = self::YEAR; 3559 } 3560 3561 return $this->copyPart($format, $locale); 3562 } 3563 3564 3565 /** 3566 * Sets a new year 3567 * If the year is between 0 and 69, 2000 will be set (2000-2069) 3568 * If the year if between 70 and 99, 1999 will be set (1970-1999) 3569 * 3 or 4 digit years are set as expected. If you need to set year 0-99 3570 * use set() instead. 3571 * Returned is the new date object 3572 * 3573 * @param string|integer|array|Zend_Date $year Year to set 3574 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3575 * @return Zend_Date Provides a fluent interface 3576 * @throws Zend_Date_Exception 3577 */ 3578 public function setYear($year, $locale = null) 3579 { 3580 return $this->_calcvalue('set', $year, 'year', self::YEAR, $locale); 3581 } 3582 3583 3584 /** 3585 * Adds the year to the existing date object 3586 * If the year is between 0 and 69, 2000 will be added (2000-2069) 3587 * If the year if between 70 and 99, 1999 will be added (1970-1999) 3588 * 3 or 4 digit years are added as expected. If you need to add years from 0-99 3589 * use add() instead. 3590 * Returned is the new date object 3591 * 3592 * @param string|integer|array|Zend_Date $year Year to add 3593 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3594 * @return Zend_Date Provides a fluent interface 3595 * @throws Zend_Date_Exception 3596 */ 3597 public function addYear($year, $locale = null) 3598 { 3599 return $this->_calcvalue('add', $year, 'year', self::YEAR, $locale); 3600 } 3601 3602 3603 /** 3604 * Subs the year from the existing date object 3605 * If the year is between 0 and 69, 2000 will be subtracted (2000-2069) 3606 * If the year if between 70 and 99, 1999 will be subtracted (1970-1999) 3607 * 3 or 4 digit years are subtracted as expected. If you need to subtract years from 0-99 3608 * use sub() instead. 3609 * Returned is the new date object 3610 * 3611 * @param string|integer|array|Zend_Date $year Year to sub 3612 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3613 * @return Zend_Date Provides a fluent interface 3614 * @throws Zend_Date_Exception 3615 */ 3616 public function subYear($year, $locale = null) 3617 { 3618 return $this->_calcvalue('sub', $year, 'year', self::YEAR, $locale); 3619 } 3620 3621 3622 /** 3623 * Compares the year with the existing date object, ignoring other date parts. 3624 * For example: 10.03.2000 -> 15.02.2000 -> true 3625 * Returns if equal, earlier or later 3626 * 3627 * @param string|integer|array|Zend_Date $year Year to compare 3628 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3629 * @return integer 0 = equal, 1 = later, -1 = earlier 3630 * @throws Zend_Date_Exception 3631 */ 3632 public function compareYear($year, $locale = null) 3633 { 3634 return $this->_calcvalue('cmp', $year, 'year', self::YEAR, $locale); 3635 } 3636 3637 3638 /** 3639 * Returns only the month from the date object as new object. 3640 * For example: 10.May.2000 10:30:00 -> 01.May.1970 00:00:00 3641 * 3642 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3643 * @return Zend_Date 3644 */ 3645 public function getMonth($locale = null) 3646 { 3647 if (self::$_options['format_type'] == 'php') { 3648 $format = 'm'; 3649 } else { 3650 $format = self::MONTH; 3651 } 3652 3653 return $this->copyPart($format, $locale); 3654 } 3655 3656 3657 /** 3658 * Returns the calculated month 3659 * 3660 * @param string $calc Calculation to make 3661 * @param string|integer|array|Zend_Date $month Month to calculate with, if null the actual month is taken 3662 * @param string|Zend_Locale $locale Locale for parsing input 3663 * @return integer|Zend_Date new time 3664 * @throws Zend_Date_Exception 3665 */ 3666 private function _month($calc, $month, $locale) 3667 { 3668 if ($month === null) { 3669 // require_once 'Zend/Date/Exception.php'; 3670 throw new Zend_Date_Exception('parameter $month must be set, null is not allowed'); 3671 } 3672 3673 if ($locale === null) { 3674 $locale = $this->getLocale(); 3675 } 3676 3677 if ($month instanceof Zend_Date) { 3678 // extract month from object 3679 $found = $month->toString(self::MONTH_SHORT, 'iso', $locale); 3680 } else { 3681 if (is_numeric($month)) { 3682 $found = $month; 3683 } else if (is_array($month)) { 3684 if (isset($month['month']) === true) { 3685 $month = $month['month']; 3686 } else { 3687 // require_once 'Zend/Date/Exception.php'; 3688 throw new Zend_Date_Exception("no month given in array"); 3689 } 3690 } else { 3691 $monthlist = Zend_Locale_Data::getList($locale, 'month'); 3692 $monthlist2 = Zend_Locale_Data::getList($locale, 'month', array('gregorian', 'format', 'abbreviated')); 3693 3694 $monthlist = array_merge($monthlist, $monthlist2); 3695 $found = 0; 3696 $cnt = 0; 3697 foreach ($monthlist as $key => $value) { 3698 if (strtoupper($value) == strtoupper($month)) { 3699 $found = ($key % 12) + 1; 3700 break; 3701 } 3702 ++$cnt; 3703 } 3704 if ($found == 0) { 3705 foreach ($monthlist2 as $key => $value) { 3706 if (strtoupper(iconv_substr($value, 0, 1, 'UTF-8')) == strtoupper($month)) { 3707 $found = $key + 1; 3708 break; 3709 } 3710 ++$cnt; 3711 } 3712 } 3713 if ($found == 0) { 3714 // require_once 'Zend/Date/Exception.php'; 3715 throw new Zend_Date_Exception("unknown month name ($month)", 0, null, $month); 3716 } 3717 } 3718 } 3719 $return = $this->_calcdetail($calc, $found, self::MONTH_SHORT, $locale); 3720 if ($calc != 'cmp') { 3721 return $this; 3722 } 3723 return $return; 3724 } 3725 3726 3727 /** 3728 * Sets a new month 3729 * The month can be a number or a string. Setting months lower then 0 and greater then 12 3730 * will result in adding or subtracting the relevant year. (12 months equal one year) 3731 * If a localized monthname is given it will be parsed with the default locale or the optional 3732 * set locale. 3733 * Returned is the new date object 3734 * 3735 * @param string|integer|array|Zend_Date $month Month to set 3736 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3737 * @return Zend_Date Provides a fluent interface 3738 * @throws Zend_Date_Exception 3739 */ 3740 public function setMonth($month, $locale = null) 3741 { 3742 return $this->_month('set', $month, $locale); 3743 } 3744 3745 3746 /** 3747 * Adds months to the existing date object. 3748 * The month can be a number or a string. Adding months lower then 0 and greater then 12 3749 * will result in adding or subtracting the relevant year. (12 months equal one year) 3750 * If a localized monthname is given it will be parsed with the default locale or the optional 3751 * set locale. 3752 * Returned is the new date object 3753 * 3754 * @param string|integer|array|Zend_Date $month Month to add 3755 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3756 * @return Zend_Date Provides a fluent interface 3757 * @throws Zend_Date_Exception 3758 */ 3759 public function addMonth($month, $locale = null) 3760 { 3761 return $this->_month('add', $month, $locale); 3762 } 3763 3764 3765 /** 3766 * Subtracts months from the existing date object. 3767 * The month can be a number or a string. Subtracting months lower then 0 and greater then 12 3768 * will result in adding or subtracting the relevant year. (12 months equal one year) 3769 * If a localized monthname is given it will be parsed with the default locale or the optional 3770 * set locale. 3771 * Returned is the new date object 3772 * 3773 * @param string|integer|array|Zend_Date $month Month to sub 3774 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3775 * @return Zend_Date Provides a fluent interface 3776 * @throws Zend_Date_Exception 3777 */ 3778 public function subMonth($month, $locale = null) 3779 { 3780 return $this->_month('sub', $month, $locale); 3781 } 3782 3783 3784 /** 3785 * Compares the month with the existing date object, ignoring other date parts. 3786 * For example: 10.03.2000 -> 15.03.1950 -> true 3787 * Returns if equal, earlier or later 3788 * 3789 * @param string|integer|array|Zend_Date $month Month to compare 3790 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3791 * @return integer 0 = equal, 1 = later, -1 = earlier 3792 * @throws Zend_Date_Exception 3793 */ 3794 public function compareMonth($month, $locale = null) 3795 { 3796 return $this->_month('cmp', $month, $locale); 3797 } 3798 3799 3800 /** 3801 * Returns the day as new date object 3802 * Example: 20.May.1986 -> 20.Jan.1970 00:00:00 3803 * 3804 * @param Zend_Locale $locale OPTIONAL Locale for parsing input 3805 * @return Zend_Date 3806 */ 3807 public function getDay($locale = null) 3808 { 3809 return $this->copyPart(self::DAY_SHORT, $locale); 3810 } 3811 3812 /** 3813 * Returns the calculated day 3814 * 3815 * @param string $calc Type of calculation to make 3816 * @param Zend_Date $day Day to calculate, when null the actual day is calculated 3817 * @param Zend_Locale $locale Locale for parsing input 3818 * @throws Zend_Date_Exception 3819 * @return Zend_Date|integer 3820 */ 3821 private function _day($calc, $day, $locale) 3822 { 3823 if ($day === null) { 3824 // require_once 'Zend/Date/Exception.php'; 3825 throw new Zend_Date_Exception('parameter $day must be set, null is not allowed'); 3826 } 3827 3828 if ($locale === null) { 3829 $locale = $this->getLocale(); 3830 } 3831 3832 if ($day instanceof Zend_Date) { 3833 $day = $day->toString(self::DAY_SHORT, 'iso', $locale); 3834 } 3835 3836 if (is_numeric($day)) { 3837 $type = self::DAY_SHORT; 3838 } else if (is_array($day)) { 3839 if (isset($day['day']) === true) { 3840 $day = $day['day']; 3841 $type = self::WEEKDAY; 3842 } else { 3843 // require_once 'Zend/Date/Exception.php'; 3844 throw new Zend_Date_Exception("no day given in array"); 3845 } 3846 } else { 3847 switch (iconv_strlen($day, 'UTF-8')) { 3848 case 1 : 3849 $type = self::WEEKDAY_NARROW; 3850 break; 3851 case 2: 3852 $type = self::WEEKDAY_NAME; 3853 break; 3854 case 3: 3855 $type = self::WEEKDAY_SHORT; 3856 break; 3857 default: 3858 $type = self::WEEKDAY; 3859 break; 3860 } 3861 } 3862 $return = $this->_calcdetail($calc, $day, $type, $locale); 3863 if ($calc != 'cmp') { 3864 return $this; 3865 } 3866 return $return; 3867 } 3868 3869 3870 /** 3871 * Sets a new day 3872 * The day can be a number or a string. Setting days lower then 0 or greater than the number of this months days 3873 * will result in adding or subtracting the relevant month. 3874 * If a localized dayname is given it will be parsed with the default locale or the optional 3875 * set locale. 3876 * Returned is the new date object 3877 * Example: setDay('Montag', 'de_AT'); will set the monday of this week as day. 3878 * 3879 * @param string|integer|array|Zend_Date $day Day to set 3880 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3881 * @return Zend_Date Provides a fluent interface 3882 * @throws Zend_Date_Exception 3883 */ 3884 public function setDay($day, $locale = null) 3885 { 3886 return $this->_day('set', $day, $locale); 3887 } 3888 3889 3890 /** 3891 * Adds days to the existing date object. 3892 * The day can be a number or a string. Adding days lower then 0 or greater than the number of this months days 3893 * will result in adding or subtracting the relevant month. 3894 * If a localized dayname is given it will be parsed with the default locale or the optional 3895 * set locale. 3896 * 3897 * @param string|integer|array|Zend_Date $day Day to add 3898 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3899 * @return Zend_Date Provides a fluent interface 3900 * @throws Zend_Date_Exception 3901 */ 3902 public function addDay($day, $locale = null) 3903 { 3904 return $this->_day('add', $day, $locale); 3905 } 3906 3907 3908 /** 3909 * Subtracts days from the existing date object. 3910 * The day can be a number or a string. Subtracting days lower then 0 or greater than the number of this months days 3911 * will result in adding or subtracting the relevant month. 3912 * If a localized dayname is given it will be parsed with the default locale or the optional 3913 * set locale. 3914 * 3915 * @param string|integer|array|Zend_Date $day Day to sub 3916 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3917 * @return Zend_Date Provides a fluent interface 3918 * @throws Zend_Date_Exception 3919 */ 3920 public function subDay($day, $locale = null) 3921 { 3922 return $this->_day('sub', $day, $locale); 3923 } 3924 3925 3926 /** 3927 * Compares the day with the existing date object, ignoring other date parts. 3928 * For example: 'Monday', 'en' -> 08.Jan.2007 -> 0 3929 * Returns if equal, earlier or later 3930 * 3931 * @param string|integer|array|Zend_Date $day Day to compare 3932 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3933 * @return integer 0 = equal, 1 = later, -1 = earlier 3934 * @throws Zend_Date_Exception 3935 */ 3936 public function compareDay($day, $locale = null) 3937 { 3938 return $this->_day('cmp', $day, $locale); 3939 } 3940 3941 3942 /** 3943 * Returns the weekday as new date object 3944 * Weekday is always from 1-7 3945 * Example: 09-Jan-2007 -> 2 = Tuesday -> 02-Jan-1970 (when 02.01.1970 is also Tuesday) 3946 * 3947 * @param Zend_Locale $locale OPTIONAL Locale for parsing input 3948 * @return Zend_Date 3949 */ 3950 public function getWeekday($locale = null) 3951 { 3952 if (self::$_options['format_type'] == 'php') { 3953 $format = 'l'; 3954 } else { 3955 $format = self::WEEKDAY; 3956 } 3957 3958 return $this->copyPart($format, $locale); 3959 } 3960 3961 3962 /** 3963 * Returns the calculated weekday 3964 * 3965 * @param string $calc Type of calculation to make 3966 * @param Zend_Date $weekday Weekday to calculate, when null the actual weekday is calculated 3967 * @param Zend_Locale $locale Locale for parsing input 3968 * @return Zend_Date|integer 3969 * @throws Zend_Date_Exception 3970 */ 3971 private function _weekday($calc, $weekday, $locale) 3972 { 3973 if ($weekday === null) { 3974 // require_once 'Zend/Date/Exception.php'; 3975 throw new Zend_Date_Exception('parameter $weekday must be set, null is not allowed'); 3976 } 3977 3978 if ($locale === null) { 3979 $locale = $this->getLocale(); 3980 } 3981 3982 if ($weekday instanceof Zend_Date) { 3983 $weekday = $weekday->toString(self::WEEKDAY_8601, 'iso', $locale); 3984 } 3985 3986 if (is_numeric($weekday)) { 3987 $type = self::WEEKDAY_8601; 3988 } else if (is_array($weekday)) { 3989 if (isset($weekday['weekday']) === true) { 3990 $weekday = $weekday['weekday']; 3991 $type = self::WEEKDAY; 3992 } else { 3993 // require_once 'Zend/Date/Exception.php'; 3994 throw new Zend_Date_Exception("no weekday given in array"); 3995 } 3996 } else { 3997 switch(iconv_strlen($weekday, 'UTF-8')) { 3998 case 1: 3999 $type = self::WEEKDAY_NARROW; 4000 break; 4001 case 2: 4002 $type = self::WEEKDAY_NAME; 4003 break; 4004 case 3: 4005 $type = self::WEEKDAY_SHORT; 4006 break; 4007 default: 4008 $type = self::WEEKDAY; 4009 break; 4010 } 4011 } 4012 $return = $this->_calcdetail($calc, $weekday, $type, $locale); 4013 if ($calc != 'cmp') { 4014 return $this; 4015 } 4016 return $return; 4017 } 4018 4019 4020 /** 4021 * Sets a new weekday 4022 * The weekday can be a number or a string. If a localized weekday name is given, 4023 * then it will be parsed as a date in $locale (defaults to the same locale as $this). 4024 * Returned is the new date object. 4025 * Example: setWeekday(3); will set the wednesday of this week as day. 4026 * 4027 * @param string|integer|array|Zend_Date $weekday Weekday to set 4028 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4029 * @return Zend_Date Provides a fluent interface 4030 * @throws Zend_Date_Exception 4031 */ 4032 public function setWeekday($weekday, $locale = null) 4033 { 4034 return $this->_weekday('set', $weekday, $locale); 4035 } 4036 4037 4038 /** 4039 * Adds weekdays to the existing date object. 4040 * The weekday can be a number or a string. 4041 * If a localized dayname is given it will be parsed with the default locale or the optional 4042 * set locale. 4043 * Returned is the new date object 4044 * Example: addWeekday(3); will add the difference of days from the begining of the month until 4045 * wednesday. 4046 * 4047 * @param string|integer|array|Zend_Date $weekday Weekday to add 4048 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4049 * @return Zend_Date Provides a fluent interface 4050 * @throws Zend_Date_Exception 4051 */ 4052 public function addWeekday($weekday, $locale = null) 4053 { 4054 return $this->_weekday('add', $weekday, $locale); 4055 } 4056 4057 4058 /** 4059 * Subtracts weekdays from the existing date object. 4060 * The weekday can be a number or a string. 4061 * If a localized dayname is given it will be parsed with the default locale or the optional 4062 * set locale. 4063 * Returned is the new date object 4064 * Example: subWeekday(3); will subtract the difference of days from the begining of the month until 4065 * wednesday. 4066 * 4067 * @param string|integer|array|Zend_Date $weekday Weekday to sub 4068 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4069 * @return Zend_Date Provides a fluent interface 4070 * @throws Zend_Date_Exception 4071 */ 4072 public function subWeekday($weekday, $locale = null) 4073 { 4074 return $this->_weekday('sub', $weekday, $locale); 4075 } 4076 4077 4078 /** 4079 * Compares the weekday with the existing date object, ignoring other date parts. 4080 * For example: 'Monday', 'en' -> 08.Jan.2007 -> 0 4081 * Returns if equal, earlier or later 4082 * 4083 * @param string|integer|array|Zend_Date $weekday Weekday to compare 4084 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4085 * @return integer 0 = equal, 1 = later, -1 = earlier 4086 * @throws Zend_Date_Exception 4087 */ 4088 public function compareWeekday($weekday, $locale = null) 4089 { 4090 return $this->_weekday('cmp', $weekday, $locale); 4091 } 4092 4093 4094 /** 4095 * Returns the day of year as new date object 4096 * Example: 02.Feb.1986 10:00:00 -> 02.Feb.1970 00:00:00 4097 * 4098 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4099 * @return Zend_Date 4100 */ 4101 public function getDayOfYear($locale = null) 4102 { 4103 if (self::$_options['format_type'] == 'php') { 4104 $format = 'D'; 4105 } else { 4106 $format = self::DAY_OF_YEAR; 4107 } 4108 4109 return $this->copyPart($format, $locale); 4110 } 4111 4112 4113 /** 4114 * Sets a new day of year 4115 * The day of year is always a number. 4116 * Returned is the new date object 4117 * Example: 04.May.2004 -> setDayOfYear(10) -> 10.Jan.2004 4118 * 4119 * @param string|integer|array|Zend_Date $day Day of Year to set 4120 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4121 * @return Zend_Date Provides a fluent interface 4122 * @throws Zend_Date_Exception 4123 */ 4124 public function setDayOfYear($day, $locale = null) 4125 { 4126 return $this->_calcvalue('set', $day, 'day of year', self::DAY_OF_YEAR, $locale); 4127 } 4128 4129 4130 /** 4131 * Adds a day of year to the existing date object. 4132 * The day of year is always a number. 4133 * Returned is the new date object 4134 * Example: addDayOfYear(10); will add 10 days to the existing date object. 4135 * 4136 * @param string|integer|array|Zend_Date $day Day of Year to add 4137 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4138 * @return Zend_Date Provides a fluent interface 4139 * @throws Zend_Date_Exception 4140 */ 4141 public function addDayOfYear($day, $locale = null) 4142 { 4143 return $this->_calcvalue('add', $day, 'day of year', self::DAY_OF_YEAR, $locale); 4144 } 4145 4146 4147 /** 4148 * Subtracts a day of year from the existing date object. 4149 * The day of year is always a number. 4150 * Returned is the new date object 4151 * Example: subDayOfYear(10); will subtract 10 days from the existing date object. 4152 * 4153 * @param string|integer|array|Zend_Date $day Day of Year to sub 4154 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4155 * @return Zend_Date Provides a fluent interface 4156 * @throws Zend_Date_Exception 4157 */ 4158 public function subDayOfYear($day, $locale = null) 4159 { 4160 return $this->_calcvalue('sub', $day, 'day of year', self::DAY_OF_YEAR, $locale); 4161 } 4162 4163 4164 /** 4165 * Compares the day of year with the existing date object. 4166 * For example: compareDayOfYear(33) -> 02.Feb.2007 -> 0 4167 * Returns if equal, earlier or later 4168 * 4169 * @param string|integer|array|Zend_Date $day Day of Year to compare 4170 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4171 * @return integer 0 = equal, 1 = later, -1 = earlier 4172 * @throws Zend_Date_Exception 4173 */ 4174 public function compareDayOfYear($day, $locale = null) 4175 { 4176 return $this->_calcvalue('cmp', $day, 'day of year', self::DAY_OF_YEAR, $locale); 4177 } 4178 4179 4180 /** 4181 * Returns the hour as new date object 4182 * Example: 02.Feb.1986 10:30:25 -> 01.Jan.1970 10:00:00 4183 * 4184 * @param Zend_Locale $locale OPTIONAL Locale for parsing input 4185 * @return Zend_Date 4186 */ 4187 public function getHour($locale = null) 4188 { 4189 return $this->copyPart(self::HOUR, $locale); 4190 } 4191 4192 4193 /** 4194 * Sets a new hour 4195 * The hour is always a number. 4196 * Returned is the new date object 4197 * Example: 04.May.1993 13:07:25 -> setHour(7); -> 04.May.1993 07:07:25 4198 * 4199 * @param string|integer|array|Zend_Date $hour Hour to set 4200 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4201 * @return Zend_Date Provides a fluent interface 4202 * @throws Zend_Date_Exception 4203 */ 4204 public function setHour($hour, $locale = null) 4205 { 4206 return $this->_calcvalue('set', $hour, 'hour', self::HOUR_SHORT, $locale); 4207 } 4208 4209 4210 /** 4211 * Adds hours to the existing date object. 4212 * The hour is always a number. 4213 * Returned is the new date object 4214 * Example: 04.May.1993 13:07:25 -> addHour(12); -> 05.May.1993 01:07:25 4215 * 4216 * @param string|integer|array|Zend_Date $hour Hour to add 4217 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4218 * @return Zend_Date Provides a fluent interface 4219 * @throws Zend_Date_Exception 4220 */ 4221 public function addHour($hour, $locale = null) 4222 { 4223 return $this->_calcvalue('add', $hour, 'hour', self::HOUR_SHORT, $locale); 4224 } 4225 4226 4227 /** 4228 * Subtracts hours from the existing date object. 4229 * The hour is always a number. 4230 * Returned is the new date object 4231 * Example: 04.May.1993 13:07:25 -> subHour(6); -> 05.May.1993 07:07:25 4232 * 4233 * @param string|integer|array|Zend_Date $hour Hour to sub 4234 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4235 * @return Zend_Date Provides a fluent interface 4236 * @throws Zend_Date_Exception 4237 */ 4238 public function subHour($hour, $locale = null) 4239 { 4240 return $this->_calcvalue('sub', $hour, 'hour', self::HOUR_SHORT, $locale); 4241 } 4242 4243 4244 /** 4245 * Compares the hour with the existing date object. 4246 * For example: 10:30:25 -> compareHour(10) -> 0 4247 * Returns if equal, earlier or later 4248 * 4249 * @param string|integer|array|Zend_Date $hour Hour to compare 4250 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4251 * @return integer 0 = equal, 1 = later, -1 = earlier 4252 * @throws Zend_Date_Exception 4253 */ 4254 public function compareHour($hour, $locale = null) 4255 { 4256 return $this->_calcvalue('cmp', $hour, 'hour', self::HOUR_SHORT, $locale); 4257 } 4258 4259 4260 /** 4261 * Returns the minute as new date object 4262 * Example: 02.Feb.1986 10:30:25 -> 01.Jan.1970 00:30:00 4263 * 4264 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4265 * @return Zend_Date 4266 */ 4267 public function getMinute($locale = null) 4268 { 4269 if (self::$_options['format_type'] == 'php') { 4270 $format = 'i'; 4271 } else { 4272 $format = self::MINUTE; 4273 } 4274 4275 return $this->copyPart($format, $locale); 4276 } 4277 4278 4279 /** 4280 * Sets a new minute 4281 * The minute is always a number. 4282 * Returned is the new date object 4283 * Example: 04.May.1993 13:07:25 -> setMinute(29); -> 04.May.1993 13:29:25 4284 * 4285 * @param string|integer|array|Zend_Date $minute Minute to set 4286 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4287 * @return Zend_Date Provides a fluent interface 4288 * @throws Zend_Date_Exception 4289 */ 4290 public function setMinute($minute, $locale = null) 4291 { 4292 return $this->_calcvalue('set', $minute, 'minute', self::MINUTE_SHORT, $locale); 4293 } 4294 4295 4296 /** 4297 * Adds minutes to the existing date object. 4298 * The minute is always a number. 4299 * Returned is the new date object 4300 * Example: 04.May.1993 13:07:25 -> addMinute(65); -> 04.May.1993 13:12:25 4301 * 4302 * @param string|integer|array|Zend_Date $minute Minute to add 4303 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4304 * @return Zend_Date Provides a fluent interface 4305 * @throws Zend_Date_Exception 4306 */ 4307 public function addMinute($minute, $locale = null) 4308 { 4309 return $this->_calcvalue('add', $minute, 'minute', self::MINUTE_SHORT, $locale); 4310 } 4311 4312 4313 /** 4314 * Subtracts minutes from the existing date object. 4315 * The minute is always a number. 4316 * Returned is the new date object 4317 * Example: 04.May.1993 13:07:25 -> subMinute(9); -> 04.May.1993 12:58:25 4318 * 4319 * @param string|integer|array|Zend_Date $minute Minute to sub 4320 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4321 * @return Zend_Date Provides a fluent interface 4322 * @throws Zend_Date_Exception 4323 */ 4324 public function subMinute($minute, $locale = null) 4325 { 4326 return $this->_calcvalue('sub', $minute, 'minute', self::MINUTE_SHORT, $locale); 4327 } 4328 4329 4330 /** 4331 * Compares the minute with the existing date object. 4332 * For example: 10:30:25 -> compareMinute(30) -> 0 4333 * Returns if equal, earlier or later 4334 * 4335 * @param string|integer|array|Zend_Date $minute Hour to compare 4336 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4337 * @return integer 0 = equal, 1 = later, -1 = earlier 4338 * @throws Zend_Date_Exception 4339 */ 4340 public function compareMinute($minute, $locale = null) 4341 { 4342 return $this->_calcvalue('cmp', $minute, 'minute', self::MINUTE_SHORT, $locale); 4343 } 4344 4345 4346 /** 4347 * Returns the second as new date object 4348 * Example: 02.Feb.1986 10:30:25 -> 01.Jan.1970 00:00:25 4349 * 4350 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4351 * @return Zend_Date 4352 */ 4353 public function getSecond($locale = null) 4354 { 4355 if (self::$_options['format_type'] == 'php') { 4356 $format = 's'; 4357 } else { 4358 $format = self::SECOND; 4359 } 4360 4361 return $this->copyPart($format, $locale); 4362 } 4363 4364 4365 /** 4366 * Sets new seconds to the existing date object. 4367 * The second is always a number. 4368 * Returned is the new date object 4369 * Example: 04.May.1993 13:07:25 -> setSecond(100); -> 04.May.1993 13:08:40 4370 * 4371 * @param string|integer|array|Zend_Date $second Second to set 4372 * @param string|Zend_Locale $locale (Optional) Locale for parsing input 4373 * @return Zend_Date Provides a fluent interface 4374 * @throws Zend_Date_Exception 4375 */ 4376 public function setSecond($second, $locale = null) 4377 { 4378 return $this->_calcvalue('set', $second, 'second', self::SECOND_SHORT, $locale); 4379 } 4380 4381 4382 /** 4383 * Adds seconds to the existing date object. 4384 * The second is always a number. 4385 * Returned is the new date object 4386 * Example: 04.May.1993 13:07:25 -> addSecond(65); -> 04.May.1993 13:08:30 4387 * 4388 * @param string|integer|array|Zend_Date $second Second to add 4389 * @param string|Zend_Locale $locale (Optional) Locale for parsing input 4390 * @return Zend_Date Provides a fluent interface 4391 * @throws Zend_Date_Exception 4392 */ 4393 public function addSecond($second, $locale = null) 4394 { 4395 return $this->_calcvalue('add', $second, 'second', self::SECOND_SHORT, $locale); 4396 } 4397 4398 4399 /** 4400 * Subtracts seconds from the existing date object. 4401 * The second is always a number. 4402 * Returned is the new date object 4403 * Example: 04.May.1993 13:07:25 -> subSecond(10); -> 04.May.1993 13:07:15 4404 * 4405 * @param string|integer|array|Zend_Date $second Second to sub 4406 * @param string|Zend_Locale $locale (Optional) Locale for parsing input 4407 * @return Zend_Date Provides a fluent interface 4408 * @throws Zend_Date_Exception 4409 */ 4410 public function subSecond($second, $locale = null) 4411 { 4412 return $this->_calcvalue('sub', $second, 'second', self::SECOND_SHORT, $locale); 4413 } 4414 4415 4416 /** 4417 * Compares the second with the existing date object. 4418 * For example: 10:30:25 -> compareSecond(25) -> 0 4419 * Returns if equal, earlier or later 4420 * 4421 * @param string|integer|array|Zend_Date $second Second to compare 4422 * @param string|Zend_Locale $locale (Optional) Locale for parsing input 4423 * @return integer 0 = equal, 1 = later, -1 = earlier 4424 * @throws Zend_Date_Exception 4425 */ 4426 public function compareSecond($second, $locale = null) 4427 { 4428 return $this->_calcvalue('cmp', $second, 'second', self::SECOND_SHORT, $locale); 4429 } 4430 4431 4432 /** 4433 * Returns the precision for fractional seconds 4434 * 4435 * @return integer 4436 */ 4437 public function getFractionalPrecision() 4438 { 4439 return $this->_precision; 4440 } 4441 4442 4443 /** 4444 * Sets a new precision for fractional seconds 4445 * 4446 * @param integer $precision Precision for the fractional datepart 3 = milliseconds 4447 * @throws Zend_Date_Exception 4448 * @return Zend_Date Provides a fluent interface 4449 */ 4450 public function setFractionalPrecision($precision) 4451 { 4452 if (!intval($precision) or ($precision < 0) or ($precision > 9)) { 4453 // require_once 'Zend/Date/Exception.php'; 4454 throw new Zend_Date_Exception("precision ($precision) must be a positive integer less than 10", 0, null, $precision); 4455 } 4456 4457 $this->_precision = (int) $precision; 4458 if ($this->_precision < strlen($this->_fractional)) { 4459 $this->_fractional = substr($this->_fractional, 0, $this->_precision); 4460 } else { 4461 $this->_fractional = str_pad($this->_fractional, $this->_precision, '0', STR_PAD_RIGHT); 4462 } 4463 4464 return $this; 4465 } 4466 4467 4468 /** 4469 * Returns the milliseconds of the date object 4470 * 4471 * @return string 4472 */ 4473 public function getMilliSecond() 4474 { 4475 return $this->_fractional; 4476 } 4477 4478 /** 4479 * Sets new milliseconds for the date object 4480 * Example: setMilliSecond(550, 2) -> equals +5 Sec +50 MilliSec 4481 * 4482 * @param integer|Zend_Date $milli (Optional) Millisecond to set, when null the actual millisecond is set 4483 * @param integer $precision (Optional) Fraction precision of the given milliseconds 4484 * @throws Zend_Date_Exception 4485 * @return Zend_Date Provides a fluent interface 4486 */ 4487 public function setMilliSecond($milli = null, $precision = null) 4488 { 4489 if ($milli === null) { 4490 list($milli, $time) = explode(" ", microtime()); 4491 $milli = intval($milli); 4492 $precision = 6; 4493 } else if (!is_numeric($milli)) { 4494 // require_once 'Zend/Date/Exception.php'; 4495 throw new Zend_Date_Exception("invalid milli second ($milli) operand", 0, null, $milli); 4496 } 4497 4498 if ($precision === null) { 4499 $precision = $this->_precision; 4500 } 4501 4502 if (!is_int($precision) || $precision < 1 || $precision > 9) { 4503 // require_once 'Zend/Date/Exception.php'; 4504 throw new Zend_Date_Exception("precision ($precision) must be a positive integer less than 10", 0, null, $precision); 4505 } 4506 4507 $this->_fractional = 0; 4508 $this->addMilliSecond($milli, $precision); 4509 return $this; 4510 } 4511 4512 /** 4513 * Adds milliseconds to the date object 4514 * 4515 * @param integer|Zend_Date $milli (Optional) Millisecond to add, when null the actual millisecond is added 4516 * @param integer $precision (Optional) Fractional precision for the given milliseconds 4517 * @throws Zend_Date_Exception 4518 * @return Zend_Date Provides a fluent interface 4519 */ 4520 public function addMilliSecond($milli = null, $precision = null) 4521 { 4522 if ($milli === null) { 4523 list($milli, $time) = explode(" ", microtime()); 4524 $milli = intval($milli); 4525 } else if (!is_numeric($milli)) { 4526 // require_once 'Zend/Date/Exception.php'; 4527 throw new Zend_Date_Exception("invalid milli second ($milli) operand", 0, null, $milli); 4528 } 4529 4530 if ($precision === null) { 4531 // Use internal default precision 4532 // Is not as logic as using the length of the input. But this would break tests and maybe other things 4533 // as an input value of integer 10, which is used in tests, must be parsed as 10 milliseconds (real milliseconds, precision 3) 4534 // but with auto-detect of precision, 100 milliseconds would be added. 4535 $precision = $this->_precision; 4536 } 4537 4538 if (!is_int($precision) || $precision < 1 || $precision > 9) { 4539 // require_once 'Zend/Date/Exception.php'; 4540 throw new Zend_Date_Exception( 4541 "precision ($precision) must be a positive integer less than 10", 0, null, $precision 4542 ); 4543 } 4544 4545 if ($this->_precision > $precision) { 4546 $milli = $milli * pow(10, $this->_precision - $precision); 4547 } elseif ($this->_precision < $precision) { 4548 $milli = round($milli / pow(10, $precision - $this->_precision)); 4549 } 4550 4551 $this->_fractional += $milli; 4552 4553 // Add/sub milliseconds + add/sub seconds 4554 $max = pow(10, $this->_precision); 4555 // Milli includes seconds 4556 if ($this->_fractional >= $max) { 4557 while ($this->_fractional >= $max) { 4558 $this->addSecond(1); 4559 $this->_fractional -= $max; 4560 } 4561 } 4562 4563 if ($this->_fractional < 0) { 4564 while ($this->_fractional < 0) { 4565 $this->subSecond(1); 4566 $this->_fractional += $max; 4567 } 4568 } 4569 4570 if ($this->_precision > strlen($this->_fractional)) { 4571 $this->_fractional = str_pad($this->_fractional, $this->_precision, '0', STR_PAD_LEFT); 4572 } 4573 4574 return $this; 4575 } 4576 4577 4578 /** 4579 * Subtracts a millisecond 4580 * 4581 * @param integer|Zend_Date $milli (Optional) Millisecond to sub, when null the actual millisecond is subtracted 4582 * @param integer $precision (Optional) Fractional precision for the given milliseconds 4583 * @return Zend_Date Provides a fluent interface 4584 */ 4585 public function subMilliSecond($milli = null, $precision = null) 4586 { 4587 $this->addMilliSecond(0 - $milli, $precision); 4588 return $this; 4589 } 4590 4591 /** 4592 * Compares only the millisecond part, returning the difference 4593 * 4594 * @param integer|Zend_Date $milli OPTIONAL Millisecond to compare, when null the actual millisecond is compared 4595 * @param integer $precision OPTIONAL Fractional precision for the given milliseconds 4596 * @throws Zend_Date_Exception On invalid input 4597 * @return integer 0 = equal, 1 = later, -1 = earlier 4598 */ 4599 public function compareMilliSecond($milli = null, $precision = null) 4600 { 4601 if ($milli === null) { 4602 list($milli, $time) = explode(" ", microtime()); 4603 $milli = intval($milli); 4604 } else if (is_numeric($milli) === false) { 4605 // require_once 'Zend/Date/Exception.php'; 4606 throw new Zend_Date_Exception("invalid milli second ($milli) operand", 0, null, $milli); 4607 } 4608 4609 if ($precision === null) { 4610 $precision = strlen($milli); 4611 } else if (!is_int($precision) || $precision < 1 || $precision > 9) { 4612 // require_once 'Zend/Date/Exception.php'; 4613 throw new Zend_Date_Exception("precision ($precision) must be a positive integer less than 10", 0, null, $precision); 4614 } 4615 4616 if ($precision === 0) { 4617 // require_once 'Zend/Date/Exception.php'; 4618 throw new Zend_Date_Exception('precision is 0'); 4619 } 4620 4621 if ($precision != $this->_precision) { 4622 if ($precision > $this->_precision) { 4623 $diff = $precision - $this->_precision; 4624 $milli = (int) ($milli / (10 * $diff)); 4625 } else { 4626 $diff = $this->_precision - $precision; 4627 $milli = (int) ($milli * (10 * $diff)); 4628 } 4629 } 4630 4631 $comp = $this->_fractional - $milli; 4632 if ($comp < 0) { 4633 return -1; 4634 } else if ($comp > 0) { 4635 return 1; 4636 } 4637 return 0; 4638 } 4639 4640 /** 4641 * Returns the week as new date object using monday as begining of the week 4642 * Example: 12.Jan.2007 -> 08.Jan.1970 00:00:00 4643 * 4644 * @param Zend_Locale $locale OPTIONAL Locale for parsing input 4645 * @return Zend_Date 4646 */ 4647 public function getWeek($locale = null) 4648 { 4649 if (self::$_options['format_type'] == 'php') { 4650 $format = 'W'; 4651 } else { 4652 $format = self::WEEK; 4653 } 4654 4655 return $this->copyPart($format, $locale); 4656 } 4657 4658 /** 4659 * Sets a new week. The week is always a number. The day of week is not changed. 4660 * Returned is the new date object 4661 * Example: 09.Jan.2007 13:07:25 -> setWeek(1); -> 02.Jan.2007 13:07:25 4662 * 4663 * @param string|integer|array|Zend_Date $week Week to set 4664 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4665 * @return Zend_Date Provides a fluent interface 4666 * @throws Zend_Date_Exception 4667 */ 4668 public function setWeek($week, $locale = null) 4669 { 4670 return $this->_calcvalue('set', $week, 'week', self::WEEK, $locale); 4671 } 4672 4673 /** 4674 * Adds a week. The week is always a number. The day of week is not changed. 4675 * Returned is the new date object 4676 * Example: 09.Jan.2007 13:07:25 -> addWeek(1); -> 16.Jan.2007 13:07:25 4677 * 4678 * @param string|integer|array|Zend_Date $week Week to add 4679 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4680 * @return Zend_Date Provides a fluent interface 4681 * @throws Zend_Date_Exception 4682 */ 4683 public function addWeek($week, $locale = null) 4684 { 4685 return $this->_calcvalue('add', $week, 'week', self::WEEK, $locale); 4686 } 4687 4688 /** 4689 * Subtracts a week. The week is always a number. The day of week is not changed. 4690 * Returned is the new date object 4691 * Example: 09.Jan.2007 13:07:25 -> subWeek(1); -> 02.Jan.2007 13:07:25 4692 * 4693 * @param string|integer|array|Zend_Date $week Week to sub 4694 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4695 * @return Zend_Date Provides a fluent interface 4696 * @throws Zend_Date_Exception 4697 */ 4698 public function subWeek($week, $locale = null) 4699 { 4700 return $this->_calcvalue('sub', $week, 'week', self::WEEK, $locale); 4701 } 4702 4703 /** 4704 * Compares only the week part, returning the difference 4705 * Returned is the new date object 4706 * Returns if equal, earlier or later 4707 * Example: 09.Jan.2007 13:07:25 -> compareWeek(2); -> 0 4708 * 4709 * @param string|integer|array|Zend_Date $week Week to compare 4710 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4711 * @return integer 0 = equal, 1 = later, -1 = earlier 4712 */ 4713 public function compareWeek($week, $locale = null) 4714 { 4715 return $this->_calcvalue('cmp', $week, 'week', self::WEEK, $locale); 4716 } 4717 4718 /** 4719 * Sets a new standard locale for the date object. 4720 * This locale will be used for all functions 4721 * Returned is the really set locale. 4722 * Example: 'de_XX' will be set to 'de' because 'de_XX' does not exist 4723 * 'xx_YY' will be set to 'root' because 'xx' does not exist 4724 * 4725 * @param string|Zend_Locale $locale (Optional) Locale for parsing input 4726 * @throws Zend_Date_Exception When the given locale does not exist 4727 * @return Zend_Date Provides fluent interface 4728 */ 4729 public function setLocale($locale = null) 4730 { 4731 try { 4732 $this->_locale = Zend_Locale::findLocale($locale); 4733 } catch (Zend_Locale_Exception $e) { 4734 // require_once 'Zend/Date/Exception.php'; 4735 throw new Zend_Date_Exception($e->getMessage(), 0, $e); 4736 } 4737 4738 return $this; 4739 } 4740 4741 /** 4742 * Returns the actual set locale 4743 * 4744 * @return string 4745 */ 4746 public function getLocale() 4747 { 4748 return $this->_locale; 4749 } 4750 4751 /** 4752 * Checks if the given date is a real date or datepart. 4753 * Returns false if a expected datepart is missing or a datepart exceeds its possible border. 4754 * But the check will only be done for the expected dateparts which are given by format. 4755 * If no format is given the standard dateformat for the actual locale is used. 4756 * f.e. 30.February.2007 will return false if format is 'dd.MMMM.YYYY' 4757 * 4758 * @param string|array|Zend_Date $date Date to parse for correctness 4759 * @param string $format (Optional) Format for parsing the date string 4760 * @param string|Zend_Locale $locale (Optional) Locale for parsing date parts 4761 * @return boolean True when all date parts are correct 4762 */ 4763 public static function isDate($date, $format = null, $locale = null) 4764 { 4765 if (!is_string($date) && !is_numeric($date) && !($date instanceof Zend_Date) && 4766 !is_array($date)) { 4767 return false; 4768 } 4769 4770 if (($format !== null) && ($format != 'ee') && ($format != 'ss') && ($format != 'GG') && ($format != 'MM') && ($format != 'EE') && ($format != 'TT') 4771 && (Zend_Locale::isLocale($format, null, false))) { 4772 $locale = $format; 4773 $format = null; 4774 } 4775 4776 $locale = Zend_Locale::findLocale($locale); 4777 4778 if ($format === null) { 4779 $format = Zend_Locale_Format::getDateFormat($locale); 4780 } else if ((self::$_options['format_type'] == 'php') && !defined($format)) { 4781 $format = Zend_Locale_Format::convertPhpToIsoFormat($format); 4782 } 4783 4784 $format = self::_getLocalizedToken($format, $locale); 4785 if (!is_array($date)) { 4786 try { 4787 $parsed = Zend_Locale_Format::getDate($date, array('locale' => $locale, 4788 'date_format' => $format, 'format_type' => 'iso', 4789 'fix_date' => false)); 4790 } catch (Zend_Locale_Exception $e) { 4791 // Date can not be parsed 4792 return false; 4793 } 4794 } else { 4795 $parsed = $date; 4796 } 4797 4798 if (((strpos($format, 'Y') !== false) or (strpos($format, 'y') !== false)) and 4799 (!isset($parsed['year']))) { 4800 // Year expected but not found 4801 return false; 4802 } 4803 4804 if ((strpos($format, 'M') !== false) and (!isset($parsed['month']))) { 4805 // Month expected but not found 4806 return false; 4807 } 4808 4809 if ((strpos($format, 'd') !== false) and (!isset($parsed['day']))) { 4810 // Day expected but not found 4811 return false; 4812 } 4813 4814 if (((strpos($format, 'H') !== false) or (strpos($format, 'h') !== false)) and 4815 (!isset($parsed['hour']))) { 4816 // Hour expected but not found 4817 return false; 4818 } 4819 4820 if ((strpos($format, 'm') !== false) and (!isset($parsed['minute']))) { 4821 // Minute expected but not found 4822 return false; 4823 } 4824 4825 if ((strpos($format, 's') !== false) and (!isset($parsed['second']))) { 4826 // Second expected but not found 4827 return false; 4828 } 4829 4830 // Set not given dateparts 4831 if (isset($parsed['hour']) === false) { 4832 $parsed['hour'] = 12; 4833 } 4834 4835 if (isset($parsed['minute']) === false) { 4836 $parsed['minute'] = 0; 4837 } 4838 4839 if (isset($parsed['second']) === false) { 4840 $parsed['second'] = 0; 4841 } 4842 4843 if (isset($parsed['month']) === false) { 4844 $parsed['month'] = 1; 4845 } 4846 4847 if (isset($parsed['day']) === false) { 4848 $parsed['day'] = 1; 4849 } 4850 4851 if (isset($parsed['year']) === false) { 4852 $parsed['year'] = 1970; 4853 } 4854 4855 if (self::isYearLeapYear($parsed['year'])) { 4856 $parsed['year'] = 1972; 4857 } else { 4858 $parsed['year'] = 1971; 4859 } 4860 4861 $date = new self($parsed, null, $locale); 4862 $timestamp = $date->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 4863 $parsed['month'], $parsed['day'], $parsed['year']); 4864 4865 if ($parsed['year'] != $date->date('Y', $timestamp)) { 4866 // Given year differs from parsed year 4867 return false; 4868 } 4869 4870 if ($parsed['month'] != $date->date('n', $timestamp)) { 4871 // Given month differs from parsed month 4872 return false; 4873 } 4874 4875 if ($parsed['day'] != $date->date('j', $timestamp)) { 4876 // Given day differs from parsed day 4877 return false; 4878 } 4879 4880 if ($parsed['hour'] != $date->date('G', $timestamp)) { 4881 // Given hour differs from parsed hour 4882 return false; 4883 } 4884 4885 if ($parsed['minute'] != $date->date('i', $timestamp)) { 4886 // Given minute differs from parsed minute 4887 return false; 4888 } 4889 4890 if ($parsed['second'] != $date->date('s', $timestamp)) { 4891 // Given second differs from parsed second 4892 return false; 4893 } 4894 4895 return true; 4896 } 4897 4898 /** 4899 * Returns the ISO Token for all localized constants 4900 * 4901 * @param string $token Token to normalize 4902 * @param string $locale Locale to search 4903 * @return string 4904 */ 4905 protected static function _getLocalizedToken($token, $locale) 4906 { 4907 switch($token) { 4908 case self::ISO_8601 : 4909 return "yyyy-MM-ddThh:mm:ss"; 4910 break; 4911 case self::RFC_2822 : 4912 return "EEE, dd MMM yyyy HH:mm:ss"; 4913 break; 4914 case self::DATES : 4915 return Zend_Locale_Data::getContent($locale, 'date'); 4916 break; 4917 case self::DATE_FULL : 4918 return Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'full')); 4919 break; 4920 case self::DATE_LONG : 4921 return Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'long')); 4922 break; 4923 case self::DATE_MEDIUM : 4924 return Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'medium')); 4925 break; 4926 case self::DATE_SHORT : 4927 return Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'short')); 4928 break; 4929 case self::TIMES : 4930 return Zend_Locale_Data::getContent($locale, 'time'); 4931 break; 4932 case self::TIME_FULL : 4933 return Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'full')); 4934 break; 4935 case self::TIME_LONG : 4936 return Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'long')); 4937 break; 4938 case self::TIME_MEDIUM : 4939 return Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'medium')); 4940 break; 4941 case self::TIME_SHORT : 4942 return Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'short')); 4943 break; 4944 case self::DATETIME : 4945 return Zend_Locale_Data::getContent($locale, 'datetime'); 4946 break; 4947 case self::DATETIME_FULL : 4948 return Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'full')); 4949 break; 4950 case self::DATETIME_LONG : 4951 return Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'long')); 4952 break; 4953 case self::DATETIME_MEDIUM : 4954 return Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'medium')); 4955 break; 4956 case self::DATETIME_SHORT : 4957 return Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'short')); 4958 break; 4959 case self::ATOM : 4960 case self::RFC_3339 : 4961 case self::W3C : 4962 return "yyyy-MM-DD HH:mm:ss"; 4963 break; 4964 case self::COOKIE : 4965 case self::RFC_850 : 4966 return "EEEE, dd-MM-yyyy HH:mm:ss"; 4967 break; 4968 case self::RFC_822 : 4969 case self::RFC_1036 : 4970 case self::RFC_1123 : 4971 case self::RSS : 4972 return "EEE, dd MM yyyy HH:mm:ss"; 4973 break; 4974 } 4975 4976 return $token; 4977 } 4978 }