[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Zend Framework 4 * 5 * LICENSE 6 * 7 * This source file is subject to the new BSD license that is bundled 8 * with this package in the file LICENSE.txt. 9 * It is also available through the world-wide-web at this URL: 10 * http://framework.zend.com/license/new-bsd 11 * If you did not receive a copy of the license and are unable to 12 * obtain it through the world-wide-web, please send an email 13 * to [email protected] so we can send you a copy immediately. 14 * 15 * @category Zend 16 * @package Zend_Date 17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 18 * @license http://framework.zend.com/license/new-bsd New BSD License 19 * @version $Id$ 20 */ 21 22 /** 23 * Include needed Date classes 24 */ 25 require_once 'Zend/Date/DateObject.php'; 26 require_once 'Zend/Locale.php'; 27 require_once 'Zend/Locale/Format.php'; 28 require_once 'Zend/Locale/Math.php'; 29 30 /** 31 * @category Zend 32 * @package Zend_Date 33 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 34 * @license http://framework.zend.com/license/new-bsd New BSD License 35 */ 36 class Zend_Date extends Zend_Date_DateObject 37 { 38 private $_locale = null; 39 40 // Fractional second variables 41 private $_fractional = 0; 42 private $_precision = 3; 43 44 private static $_options = array( 45 'format_type' => 'iso', // format for date strings 'iso' or 'php' 46 'fix_dst' => true, // fix dst on summer/winter time change 47 'extend_month' => false, // false - addMonth like SQL, true like excel 48 'cache' => null, // cache to set 49 'timesync' => null // timesync server to set 50 ); 51 52 // Class wide Date Constants 53 const DAY = 'dd'; 54 const DAY_SHORT = 'd'; 55 const DAY_SUFFIX = 'SS'; 56 const DAY_OF_YEAR = 'D'; 57 const WEEKDAY = 'EEEE'; 58 const WEEKDAY_SHORT = 'EEE'; 59 const WEEKDAY_NARROW = 'E'; 60 const WEEKDAY_NAME = 'EE'; 61 const WEEKDAY_8601 = 'eee'; 62 const WEEKDAY_DIGIT = 'e'; 63 const WEEK = 'ww'; 64 const MONTH = 'MM'; 65 const MONTH_SHORT = 'M'; 66 const MONTH_DAYS = 'ddd'; 67 const MONTH_NAME = 'MMMM'; 68 const MONTH_NAME_SHORT = 'MMM'; 69 const MONTH_NAME_NARROW = 'MMMMM'; 70 const YEAR = 'y'; 71 const YEAR_SHORT = 'yy'; 72 const YEAR_8601 = 'Y'; 73 const YEAR_SHORT_8601 = 'YY'; 74 const LEAPYEAR = 'l'; 75 const MERIDIEM = 'a'; 76 const SWATCH = 'B'; 77 const HOUR = 'HH'; 78 const HOUR_SHORT = 'H'; 79 const HOUR_AM = 'hh'; 80 const HOUR_SHORT_AM = 'h'; 81 const MINUTE = 'mm'; 82 const MINUTE_SHORT = 'm'; 83 const SECOND = 'ss'; 84 const SECOND_SHORT = 's'; 85 const MILLISECOND = 'S'; 86 const TIMEZONE_NAME = 'zzzz'; 87 const DAYLIGHT = 'I'; 88 const GMT_DIFF = 'Z'; 89 const GMT_DIFF_SEP = 'ZZZZ'; 90 const TIMEZONE = 'z'; 91 const TIMEZONE_SECS = 'X'; 92 const ISO_8601 = 'c'; 93 const RFC_2822 = 'r'; 94 const TIMESTAMP = 'U'; 95 const ERA = 'G'; 96 const ERA_NAME = 'GGGG'; 97 const ERA_NARROW = 'GGGGG'; 98 const DATES = 'F'; 99 const DATE_FULL = 'FFFFF'; 100 const DATE_LONG = 'FFFF'; 101 const DATE_MEDIUM = 'FFF'; 102 const DATE_SHORT = 'FF'; 103 const TIMES = 'WW'; 104 const TIME_FULL = 'TTTTT'; 105 const TIME_LONG = 'TTTT'; 106 const TIME_MEDIUM = 'TTT'; 107 const TIME_SHORT = 'TT'; 108 const DATETIME = 'K'; 109 const DATETIME_FULL = 'KKKKK'; 110 const DATETIME_LONG = 'KKKK'; 111 const DATETIME_MEDIUM = 'KKK'; 112 const DATETIME_SHORT = 'KK'; 113 const ATOM = 'OOO'; 114 const COOKIE = 'CCC'; 115 const RFC_822 = 'R'; 116 const RFC_850 = 'RR'; 117 const RFC_1036 = 'RRR'; 118 const RFC_1123 = 'RRRR'; 119 const RFC_3339 = 'RRRRR'; 120 const RSS = 'SSS'; 121 const W3C = 'WWW'; 122 123 /** 124 * Generates the standard date object, could be a unix timestamp, localized date, 125 * string, integer, array and so on. Also parts of dates or time are supported 126 * Always set the default timezone: http://php.net/date_default_timezone_set 127 * For example, in your bootstrap: date_default_timezone_set('America/Los_Angeles'); 128 * For detailed instructions please look in the docu. 129 * 130 * @param string|integer|Zend_Date|array $date OPTIONAL Date value or value of date part to set 131 * ,depending on $part. If null the actual time is set 132 * @param string $part OPTIONAL Defines the input format of $date 133 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 134 * @return Zend_Date 135 * @throws Zend_Date_Exception 136 */ 137 public function __construct($date = null, $part = null, $locale = null) 138 { 139 if (is_object($date) and !($date instanceof Zend_TimeSync_Protocol) and 140 !($date instanceof Zend_Date)) { 141 if ($locale instanceof Zend_Locale) { 142 $locale = $date; 143 $date = null; 144 $part = null; 145 } else { 146 $date = (string) $date; 147 } 148 } 149 150 if (($date !== null) and !is_array($date) and !($date instanceof Zend_TimeSync_Protocol) and 151 !($date instanceof Zend_Date) and !defined($date) and Zend_Locale::isLocale($date, true, false)) { 152 $locale = $date; 153 $date = null; 154 $part = null; 155 } else if (($part !== null) and !defined($part) and Zend_Locale::isLocale($part, true, false)) { 156 $locale = $part; 157 $part = null; 158 } 159 160 $this->setLocale($locale); 161 if (is_string($date) && ($part === null) && (strlen($date) <= 5)) { 162 $part = $date; 163 $date = null; 164 } 165 166 if ($date === null) { 167 if ($part === null) { 168 $date = time(); 169 } else if ($part !== self::TIMESTAMP) { 170 $date = self::now($locale); 171 $date = $date->get($part); 172 } 173 } 174 175 if ($date instanceof Zend_TimeSync_Protocol) { 176 $date = $date->getInfo(); 177 $date = $this->_getTime($date['offset']); 178 $part = null; 179 } else if (parent::$_defaultOffset != 0) { 180 $date = $this->_getTime(parent::$_defaultOffset); 181 } 182 183 // set the timezone and offset for $this 184 $zone = @date_default_timezone_get(); 185 $this->setTimezone($zone); 186 187 // try to get timezone from date-string 188 if (!is_int($date)) { 189 $zone = $this->getTimezoneFromString($date); 190 $this->setTimezone($zone); 191 } 192 193 // set datepart 194 if (($part !== null && $part !== self::TIMESTAMP) or (!is_numeric($date))) { 195 // switch off dst handling for value setting 196 $this->setUnixTimestamp($this->getGmtOffset()); 197 $this->set($date, $part, $this->_locale); 198 199 // DST fix 200 if (is_array($date) === true) { 201 if (!isset($date['hour'])) { 202 $date['hour'] = 0; 203 } 204 205 $hour = $this->toString('H', 'iso', true); 206 $hour = $date['hour'] - $hour; 207 switch ($hour) { 208 case 1 : 209 case -23 : 210 $this->addTimestamp(3600); 211 break; 212 case -1 : 213 case 23 : 214 $this->subTimestamp(3600); 215 break; 216 case 2 : 217 case -22 : 218 $this->addTimestamp(7200); 219 break; 220 case -2 : 221 case 22 : 222 $this->subTimestamp(7200); 223 break; 224 } 225 } 226 } else { 227 $this->setUnixTimestamp($date); 228 } 229 } 230 231 /** 232 * Sets class wide options, if no option was given, the actual set options will be returned 233 * 234 * @param array $options Options to set 235 * @throws Zend_Date_Exception 236 * @return Options array if no option was given 237 */ 238 public static function setOptions(array $options = array()) 239 { 240 if (empty($options)) { 241 return self::$_options; 242 } 243 244 foreach ($options as $name => $value) { 245 $name = strtolower($name); 246 247 if (array_key_exists($name, self::$_options)) { 248 switch($name) { 249 case 'format_type' : 250 if ((strtolower($value) != 'php') && (strtolower($value) != 'iso')) { 251 require_once 'Zend/Date/Exception.php'; 252 throw new Zend_Date_Exception("Unknown format type ($value) for dates, only 'iso' and 'php' supported", 0, null, $value); 253 } 254 break; 255 case 'fix_dst' : 256 if (!is_bool($value)) { 257 require_once 'Zend/Date/Exception.php'; 258 throw new Zend_Date_Exception("'fix_dst' has to be boolean", 0, null, $value); 259 } 260 break; 261 case 'extend_month' : 262 if (!is_bool($value)) { 263 require_once 'Zend/Date/Exception.php'; 264 throw new Zend_Date_Exception("'extend_month' has to be boolean", 0, null, $value); 265 } 266 break; 267 case 'cache' : 268 if ($value === null) { 269 parent::$_cache = null; 270 } else { 271 if (!$value instanceof Zend_Cache_Core) { 272 require_once 'Zend/Date/Exception.php'; 273 throw new Zend_Date_Exception("Instance of Zend_Cache expected"); 274 } 275 276 parent::$_cache = $value; 277 Zend_Locale_Data::setCache($value); 278 } 279 break; 280 case 'timesync' : 281 if ($value === null) { 282 parent::$_defaultOffset = 0; 283 } else { 284 if (!$value instanceof Zend_TimeSync_Protocol) { 285 require_once 'Zend/Date/Exception.php'; 286 throw new Zend_Date_Exception("Instance of Zend_TimeSync expected"); 287 } 288 289 $date = $value->getInfo(); 290 parent::$_defaultOffset = $date['offset']; 291 } 292 break; 293 } 294 self::$_options[$name] = $value; 295 } 296 else { 297 require_once 'Zend/Date/Exception.php'; 298 throw new Zend_Date_Exception("Unknown option: $name = $value"); 299 } 300 } 301 } 302 303 /** 304 * Returns this object's internal UNIX timestamp (equivalent to Zend_Date::TIMESTAMP). 305 * If the timestamp is too large for integers, then the return value will be a string. 306 * This function does not return the timestamp as an object. 307 * Use clone() or copyPart() instead. 308 * 309 * @return integer|string UNIX timestamp 310 */ 311 public function getTimestamp() 312 { 313 return $this->getUnixTimestamp(); 314 } 315 316 /** 317 * Returns the calculated timestamp 318 * HINT: timestamps are always GMT 319 * 320 * @param string $calc Type of calculation to make 321 * @param string|integer|array|Zend_Date $stamp Timestamp to calculate, when null the actual timestamp is calculated 322 * @return Zend_Date|integer 323 * @throws Zend_Date_Exception 324 */ 325 private function _timestamp($calc, $stamp) 326 { 327 if ($stamp instanceof Zend_Date) { 328 // extract timestamp from object 329 $stamp = $stamp->getTimestamp(); 330 } 331 332 if (is_array($stamp)) { 333 if (isset($stamp['timestamp']) === true) { 334 $stamp = $stamp['timestamp']; 335 } else { 336 require_once 'Zend/Date/Exception.php'; 337 throw new Zend_Date_Exception('no timestamp given in array'); 338 } 339 } 340 341 if ($calc === 'set') { 342 $return = $this->setUnixTimestamp($stamp); 343 } else { 344 $return = $this->_calcdetail($calc, $stamp, self::TIMESTAMP, null); 345 } 346 if ($calc != 'cmp') { 347 return $this; 348 } 349 return $return; 350 } 351 352 /** 353 * Sets a new timestamp 354 * 355 * @param integer|string|array|Zend_Date $timestamp Timestamp to set 356 * @return Zend_Date Provides fluid interface 357 * @throws Zend_Date_Exception 358 */ 359 public function setTimestamp($timestamp) 360 { 361 return $this->_timestamp('set', $timestamp); 362 } 363 364 /** 365 * Adds a timestamp 366 * 367 * @param integer|string|array|Zend_Date $timestamp Timestamp to add 368 * @return Zend_Date Provides fluid interface 369 * @throws Zend_Date_Exception 370 */ 371 public function addTimestamp($timestamp) 372 { 373 return $this->_timestamp('add', $timestamp); 374 } 375 376 /** 377 * Subtracts a timestamp 378 * 379 * @param integer|string|array|Zend_Date $timestamp Timestamp to sub 380 * @return Zend_Date Provides fluid interface 381 * @throws Zend_Date_Exception 382 */ 383 public function subTimestamp($timestamp) 384 { 385 return $this->_timestamp('sub', $timestamp); 386 } 387 388 /** 389 * Compares two timestamps, returning the difference as integer 390 * 391 * @param integer|string|array|Zend_Date $timestamp Timestamp to compare 392 * @return integer 0 = equal, 1 = later, -1 = earlier 393 * @throws Zend_Date_Exception 394 */ 395 public function compareTimestamp($timestamp) 396 { 397 return $this->_timestamp('cmp', $timestamp); 398 } 399 400 /** 401 * Returns a string representation of the object 402 * Supported format tokens are: 403 * G - era, y - year, Y - ISO year, M - month, w - week of year, D - day of year, d - day of month 404 * E - day of week, e - number of weekday (1-7), h - hour 1-12, H - hour 0-23, m - minute, s - second 405 * A - milliseconds of day, z - timezone, Z - timezone offset, S - fractional second, a - period of day 406 * 407 * Additionally format tokens but non ISO conform are: 408 * SS - day suffix, eee - php number of weekday(0-6), ddd - number of days per month 409 * l - Leap year, B - swatch internet time, I - daylight saving time, X - timezone offset in seconds 410 * r - RFC2822 format, U - unix timestamp 411 * 412 * Not supported ISO tokens are 413 * u - extended year, Q - quarter, q - quarter, L - stand alone month, W - week of month 414 * F - day of week of month, g - modified julian, c - stand alone weekday, k - hour 0-11, K - hour 1-24 415 * v - wall zone 416 * 417 * @param string $format OPTIONAL Rule for formatting output. If null the default date format is used 418 * @param string $type OPTIONAL Type for the format string which overrides the standard setting 419 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 420 * @return string 421 */ 422 public function toString($format = null, $type = null, $locale = null) 423 { 424 if (is_object($format)) { 425 if ($format instanceof Zend_Locale) { 426 $locale = $format; 427 $format = null; 428 } else { 429 $format = (string) $format; 430 } 431 } 432 433 if (is_object($type)) { 434 if ($type instanceof Zend_Locale) { 435 $locale = $type; 436 $type = null; 437 } else { 438 $type = (string) $type; 439 } 440 } 441 442 if (($format !== null) && !defined($format) 443 && ($format != 'ee') && ($format != 'ss') && ($format != 'GG') && ($format != 'MM') && ($format != 'EE') && ($format != 'TT') 444 && Zend_Locale::isLocale($format, null, false)) { 445 $locale = $format; 446 $format = null; 447 } 448 449 if (($type !== null) and ($type != 'php') and ($type != 'iso') and 450 Zend_Locale::isLocale($type, null, false)) { 451 $locale = $type; 452 $type = null; 453 } 454 455 if ($locale === null) { 456 $locale = $this->getLocale(); 457 } 458 459 if ($format === null) { 460 $format = Zend_Locale_Format::getDateFormat($locale) . ' ' . Zend_Locale_Format::getTimeFormat($locale); 461 } else if (((self::$_options['format_type'] == 'php') && ($type === null)) or ($type == 'php')) { 462 $format = Zend_Locale_Format::convertPhpToIsoFormat($format); 463 } 464 465 return $this->date($this->_toToken($format, $locale), $this->getUnixTimestamp(), false); 466 } 467 468 /** 469 * Returns a string representation of the date which is equal with the timestamp 470 * 471 * @return string 472 */ 473 public function __toString() 474 { 475 return $this->toString(null, $this->_locale); 476 } 477 478 /** 479 * Returns a integer representation of the object 480 * But returns false when the given part is no value f.e. Month-Name 481 * 482 * @param string|integer|Zend_Date $part OPTIONAL Defines the date or datepart to return as integer 483 * @return integer|false 484 */ 485 public function toValue($part = null) 486 { 487 $result = $this->get($part); 488 if (is_numeric($result)) { 489 return intval("$result"); 490 } else { 491 return false; 492 } 493 } 494 495 /** 496 * Returns an array representation of the object 497 * 498 * @return array 499 */ 500 public function toArray() 501 { 502 return array('day' => $this->toString(self::DAY_SHORT, 'iso'), 503 'month' => $this->toString(self::MONTH_SHORT, 'iso'), 504 'year' => $this->toString(self::YEAR, 'iso'), 505 'hour' => $this->toString(self::HOUR_SHORT, 'iso'), 506 'minute' => $this->toString(self::MINUTE_SHORT, 'iso'), 507 'second' => $this->toString(self::SECOND_SHORT, 'iso'), 508 'timezone' => $this->toString(self::TIMEZONE, 'iso'), 509 'timestamp' => $this->toString(self::TIMESTAMP, 'iso'), 510 'weekday' => $this->toString(self::WEEKDAY_8601, 'iso'), 511 'dayofyear' => $this->toString(self::DAY_OF_YEAR, 'iso'), 512 'week' => $this->toString(self::WEEK, 'iso'), 513 'gmtsecs' => $this->toString(self::TIMEZONE_SECS, 'iso')); 514 } 515 516 /** 517 * Returns a representation of a date or datepart 518 * This could be for example a localized monthname, the time without date, 519 * the era or only the fractional seconds. There are about 50 different supported date parts. 520 * For a complete list of supported datepart values look into the docu 521 * 522 * @param string $part OPTIONAL Part of the date to return, if null the timestamp is returned 523 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 524 * @return string date or datepart 525 */ 526 public function get($part = null, $locale = null) 527 { 528 if ($locale === null) { 529 $locale = $this->getLocale(); 530 } 531 532 if (($part !== null) && !defined($part) 533 && ($part != 'ee') && ($part != 'ss') && ($part != 'GG') && ($part != 'MM') && ($part != 'EE') && ($part != 'TT') 534 && Zend_Locale::isLocale($part, null, false)) { 535 $locale = $part; 536 $part = null; 537 } 538 539 if ($part === null) { 540 $part = self::TIMESTAMP; 541 } else if (self::$_options['format_type'] == 'php') { 542 $part = Zend_Locale_Format::convertPhpToIsoFormat($part); 543 } 544 545 return $this->date($this->_toToken($part, $locale), $this->getUnixTimestamp(), false); 546 } 547 548 /** 549 * Internal method to apply tokens 550 * 551 * @param string $part 552 * @param string $locale 553 * @return string 554 */ 555 private function _toToken($part, $locale) { 556 // get format tokens 557 $comment = false; 558 $format = ''; 559 $orig = ''; 560 for ($i = 0; $i < strlen($part); ++$i) { 561 if ($part[$i] == "'") { 562 $comment = $comment ? false : true; 563 if (isset($part[$i+1]) && ($part[$i+1] == "'")) { 564 $comment = $comment ? false : true; 565 $format .= "\\'"; 566 ++$i; 567 } 568 569 $orig = ''; 570 continue; 571 } 572 573 if ($comment) { 574 $format .= '\\' . $part[$i]; 575 $orig = ''; 576 } else { 577 $orig .= $part[$i]; 578 if (!isset($part[$i+1]) || (isset($orig[0]) && ($orig[0] != $part[$i+1]))) { 579 $format .= $this->_parseIsoToDate($orig, $locale); 580 $orig = ''; 581 } 582 } 583 } 584 585 return $format; 586 } 587 588 /** 589 * Internal parsing method 590 * 591 * @param string $token 592 * @param string $locale 593 * @return string 594 */ 595 private function _parseIsoToDate($token, $locale) { 596 switch($token) { 597 case self::DAY : 598 return 'd'; 599 break; 600 601 case self::WEEKDAY_SHORT : 602 $weekday = strtolower($this->date('D', $this->getUnixTimestamp(), false)); 603 $day = Zend_Locale_Data::getContent($locale, 'day', array('gregorian', 'format', 'wide', $weekday)); 604 return $this->_toComment(iconv_substr($day, 0, 3, 'UTF-8')); 605 break; 606 607 case self::DAY_SHORT : 608 return 'j'; 609 break; 610 611 case self::WEEKDAY : 612 $weekday = strtolower($this->date('D', $this->getUnixTimestamp(), false)); 613 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'day', array('gregorian', 'format', 'wide', $weekday))); 614 break; 615 616 case self::WEEKDAY_8601 : 617 return 'N'; 618 break; 619 620 case 'ee' : 621 return $this->_toComment(str_pad($this->date('N', $this->getUnixTimestamp(), false), 2, '0', STR_PAD_LEFT)); 622 break; 623 624 case self::DAY_SUFFIX : 625 return 'S'; 626 break; 627 628 case self::WEEKDAY_DIGIT : 629 return 'w'; 630 break; 631 632 case self::DAY_OF_YEAR : 633 return 'z'; 634 break; 635 636 case 'DDD' : 637 return $this->_toComment(str_pad($this->date('z', $this->getUnixTimestamp(), false), 3, '0', STR_PAD_LEFT)); 638 break; 639 640 case 'DD' : 641 return $this->_toComment(str_pad($this->date('z', $this->getUnixTimestamp(), false), 2, '0', STR_PAD_LEFT)); 642 break; 643 644 case self::WEEKDAY_NARROW : 645 case 'EEEEE' : 646 $weekday = strtolower($this->date('D', $this->getUnixTimestamp(), false)); 647 $day = Zend_Locale_Data::getContent($locale, 'day', array('gregorian', 'format', 'abbreviated', $weekday)); 648 return $this->_toComment(iconv_substr($day, 0, 1, 'UTF-8')); 649 break; 650 651 case self::WEEKDAY_NAME : 652 $weekday = strtolower($this->date('D', $this->getUnixTimestamp(), false)); 653 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'day', array('gregorian', 'format', 'abbreviated', $weekday))); 654 break; 655 656 case 'w' : 657 $week = $this->date('W', $this->getUnixTimestamp(), false); 658 return $this->_toComment(($week[0] == '0') ? $week[1] : $week); 659 break; 660 661 case self::WEEK : 662 return 'W'; 663 break; 664 665 case self::MONTH_NAME : 666 $month = $this->date('n', $this->getUnixTimestamp(), false); 667 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'month', array('gregorian', 'format', 'wide', $month))); 668 break; 669 670 case self::MONTH : 671 return 'm'; 672 break; 673 674 case self::MONTH_NAME_SHORT : 675 $month = $this->date('n', $this->getUnixTimestamp(), false); 676 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'month', array('gregorian', 'format', 'abbreviated', $month))); 677 break; 678 679 case self::MONTH_SHORT : 680 return 'n'; 681 break; 682 683 case self::MONTH_DAYS : 684 return 't'; 685 break; 686 687 case self::MONTH_NAME_NARROW : 688 $month = $this->date('n', $this->getUnixTimestamp(), false); 689 $mon = Zend_Locale_Data::getContent($locale, 'month', array('gregorian', 'format', 'abbreviated', $month)); 690 return $this->_toComment(iconv_substr($mon, 0, 1, 'UTF-8')); 691 break; 692 693 case self::LEAPYEAR : 694 return 'L'; 695 break; 696 697 case self::YEAR_8601 : 698 return 'o'; 699 break; 700 701 case self::YEAR : 702 return 'Y'; 703 break; 704 705 case self::YEAR_SHORT : 706 return 'y'; 707 break; 708 709 case self::YEAR_SHORT_8601 : 710 return $this->_toComment(substr($this->date('o', $this->getUnixTimestamp(), false), -2, 2)); 711 break; 712 713 case self::MERIDIEM : 714 $am = $this->date('a', $this->getUnixTimestamp(), false); 715 if ($am == 'am') { 716 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'am')); 717 } 718 719 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'pm')); 720 break; 721 722 case self::SWATCH : 723 return 'B'; 724 break; 725 726 case self::HOUR_SHORT_AM : 727 return 'g'; 728 break; 729 730 case self::HOUR_SHORT : 731 return 'G'; 732 break; 733 734 case self::HOUR_AM : 735 return 'h'; 736 break; 737 738 case self::HOUR : 739 return 'H'; 740 break; 741 742 case self::MINUTE : 743 return $this->_toComment(str_pad($this->date('i', $this->getUnixTimestamp(), false), 2, '0', STR_PAD_LEFT)); 744 break; 745 746 case self::SECOND : 747 return $this->_toComment(str_pad($this->date('s', $this->getUnixTimestamp(), false), 2, '0', STR_PAD_LEFT)); 748 break; 749 750 case self::MINUTE_SHORT : 751 return 'i'; 752 break; 753 754 case self::SECOND_SHORT : 755 return 's'; 756 break; 757 758 case self::MILLISECOND : 759 return $this->_toComment($this->getMilliSecond()); 760 break; 761 762 case self::TIMEZONE_NAME : 763 case 'vvvv' : 764 return 'e'; 765 break; 766 767 case self::DAYLIGHT : 768 return 'I'; 769 break; 770 771 case self::GMT_DIFF : 772 case 'ZZ' : 773 case 'ZZZ' : 774 return 'O'; 775 break; 776 777 case self::GMT_DIFF_SEP : 778 return 'P'; 779 break; 780 781 case self::TIMEZONE : 782 case 'v' : 783 case 'zz' : 784 case 'zzz' : 785 return 'T'; 786 break; 787 788 case self::TIMEZONE_SECS : 789 return 'Z'; 790 break; 791 792 case self::ISO_8601 : 793 return 'c'; 794 break; 795 796 case self::RFC_2822 : 797 return 'r'; 798 break; 799 800 case self::TIMESTAMP : 801 return 'U'; 802 break; 803 804 case self::ERA : 805 case 'GG' : 806 case 'GGG' : 807 $year = $this->date('Y', $this->getUnixTimestamp(), false); 808 if ($year < 0) { 809 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Abbr', '0'))); 810 } 811 812 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Abbr', '1'))); 813 break; 814 815 case self::ERA_NARROW : 816 $year = $this->date('Y', $this->getUnixTimestamp(), false); 817 if ($year < 0) { 818 return $this->_toComment(iconv_substr(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Abbr', '0')), 0, 1, 'UTF-8')) . '.'; 819 } 820 821 return $this->_toComment(iconv_substr(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Abbr', '1')), 0, 1, 'UTF-8')) . '.'; 822 break; 823 824 case self::ERA_NAME : 825 $year = $this->date('Y', $this->getUnixTimestamp(), false); 826 if ($year < 0) { 827 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Names', '0'))); 828 } 829 830 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Names', '1'))); 831 break; 832 833 case self::DATES : 834 return $this->_toToken(Zend_Locale_Format::getDateFormat($locale), $locale); 835 break; 836 837 case self::DATE_FULL : 838 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'full')), $locale); 839 break; 840 841 case self::DATE_LONG : 842 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'long')), $locale); 843 break; 844 845 case self::DATE_MEDIUM : 846 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'medium')), $locale); 847 break; 848 849 case self::DATE_SHORT : 850 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'short')), $locale); 851 break; 852 853 case self::TIMES : 854 return $this->_toToken(Zend_Locale_Format::getTimeFormat($locale), $locale); 855 break; 856 857 case self::TIME_FULL : 858 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'time', 'full'), $locale); 859 break; 860 861 case self::TIME_LONG : 862 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'time', 'long'), $locale); 863 break; 864 865 case self::TIME_MEDIUM : 866 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'time', 'medium'), $locale); 867 break; 868 869 case self::TIME_SHORT : 870 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'time', 'short'), $locale); 871 break; 872 873 case self::DATETIME : 874 return $this->_toToken(Zend_Locale_Format::getDateTimeFormat($locale), $locale); 875 break; 876 877 case self::DATETIME_FULL : 878 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'full')), $locale); 879 break; 880 881 case self::DATETIME_LONG : 882 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'long')), $locale); 883 break; 884 885 case self::DATETIME_MEDIUM : 886 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'medium')), $locale); 887 break; 888 889 case self::DATETIME_SHORT : 890 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'short')), $locale); 891 break; 892 893 case self::ATOM : 894 return 'Y\-m\-d\TH\:i\:sP'; 895 break; 896 897 case self::COOKIE : 898 return 'l\, d\-M\-y H\:i\:s e'; 899 break; 900 901 case self::RFC_822 : 902 return 'D\, d M y H\:i\:s O'; 903 break; 904 905 case self::RFC_850 : 906 return 'l\, d\-M\-y H\:i\:s e'; 907 break; 908 909 case self::RFC_1036 : 910 return 'D\, d M y H\:i\:s O'; 911 break; 912 913 case self::RFC_1123 : 914 return 'D\, d M Y H\:i\:s O'; 915 break; 916 917 case self::RFC_3339 : 918 return 'Y\-m\-d\TH\:i\:sP'; 919 break; 920 921 case self::RSS : 922 return 'D\, d M Y H\:i\:s O'; 923 break; 924 925 case self::W3C : 926 return 'Y\-m\-d\TH\:i\:sP'; 927 break; 928 } 929 930 if ($token == '') { 931 return ''; 932 } 933 934 switch ($token[0]) { 935 case 'y' : 936 if ((strlen($token) == 4) && (abs($this->getUnixTimestamp()) <= 0x7FFFFFFF)) { 937 return 'Y'; 938 } 939 940 $length = iconv_strlen($token, 'UTF-8'); 941 return $this->_toComment(str_pad($this->date('Y', $this->getUnixTimestamp(), false), $length, '0', STR_PAD_LEFT)); 942 break; 943 944 case 'Y' : 945 if ((strlen($token) == 4) && (abs($this->getUnixTimestamp()) <= 0x7FFFFFFF)) { 946 return 'o'; 947 } 948 949 $length = iconv_strlen($token, 'UTF-8'); 950 return $this->_toComment(str_pad($this->date('o', $this->getUnixTimestamp(), false), $length, '0', STR_PAD_LEFT)); 951 break; 952 953 case 'A' : 954 $length = iconv_strlen($token, 'UTF-8'); 955 $result = substr($this->getMilliSecond(), 0, 3); 956 $result += $this->date('s', $this->getUnixTimestamp(), false) * 1000; 957 $result += $this->date('i', $this->getUnixTimestamp(), false) * 60000; 958 $result += $this->date('H', $this->getUnixTimestamp(), false) * 3600000; 959 960 return $this->_toComment(str_pad($result, $length, '0', STR_PAD_LEFT)); 961 break; 962 } 963 964 return $this->_toComment($token); 965 } 966 967 /** 968 * Private function to make a comment of a token 969 * 970 * @param string $token 971 * @return string 972 */ 973 private function _toComment($token) 974 { 975 $token = str_split($token); 976 $result = ''; 977 foreach ($token as $tok) { 978 $result .= '\\' . $tok; 979 } 980 981 return $result; 982 } 983 984 /** 985 * Return digit from standard names (english) 986 * Faster implementation than locale aware searching 987 * 988 * @param string $name 989 * @return integer Number of this month 990 * @throws Zend_Date_Exception 991 */ 992 private function _getDigitFromName($name) 993 { 994 switch($name) { 995 case "Jan": 996 return 1; 997 998 case "Feb": 999 return 2; 1000 1001 case "Mar": 1002 return 3; 1003 1004 case "Apr": 1005 return 4; 1006 1007 case "May": 1008 return 5; 1009 1010 case "Jun": 1011 return 6; 1012 1013 case "Jul": 1014 return 7; 1015 1016 case "Aug": 1017 return 8; 1018 1019 case "Sep": 1020 return 9; 1021 1022 case "Oct": 1023 return 10; 1024 1025 case "Nov": 1026 return 11; 1027 1028 case "Dec": 1029 return 12; 1030 1031 default: 1032 require_once 'Zend/Date/Exception.php'; 1033 throw new Zend_Date_Exception('Month ($name) is not a known month'); 1034 } 1035 } 1036 1037 /** 1038 * Counts the exact year number 1039 * < 70 - 2000 added, >70 < 100 - 1900, others just returned 1040 * 1041 * @param integer $value year number 1042 * @return integer Number of year 1043 */ 1044 public static function getFullYear($value) 1045 { 1046 if ($value >= 0) { 1047 if ($value < 70) { 1048 $value += 2000; 1049 } else if ($value < 100) { 1050 $value += 1900; 1051 } 1052 } 1053 return $value; 1054 } 1055 1056 /** 1057 * Sets the given date as new date or a given datepart as new datepart returning the new datepart 1058 * This could be for example a localized dayname, the date without time, 1059 * the month or only the seconds. There are about 50 different supported date parts. 1060 * For a complete list of supported datepart values look into the docu 1061 * 1062 * @param string|integer|array|Zend_Date $date Date or datepart to set 1063 * @param string $part OPTIONAL Part of the date to set, if null the timestamp is set 1064 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 1065 * @return Zend_Date Provides fluid interface 1066 * @throws Zend_Date_Exception 1067 */ 1068 public function set($date, $part = null, $locale = null) 1069 { 1070 if (self::$_options['format_type'] == 'php') { 1071 $part = Zend_Locale_Format::convertPhpToIsoFormat($part); 1072 } 1073 1074 $zone = $this->getTimezoneFromString($date); 1075 $this->setTimezone($zone); 1076 1077 $this->_calculate('set', $date, $part, $locale); 1078 return $this; 1079 } 1080 1081 /** 1082 * Adds a date or datepart to the existing date, by extracting $part from $date, 1083 * and modifying this object by adding that part. The $part is then extracted from 1084 * this object and returned as an integer or numeric string (for large values, or $part's 1085 * corresponding to pre-defined formatted date strings). 1086 * This could be for example a ISO 8601 date, the hour the monthname or only the minute. 1087 * There are about 50 different supported date parts. 1088 * For a complete list of supported datepart values look into the docu. 1089 * 1090 * @param string|integer|array|Zend_Date $date Date or datepart to add 1091 * @param string $part OPTIONAL Part of the date to add, if null the timestamp is added 1092 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 1093 * @return Zend_Date Provides fluid interface 1094 * @throws Zend_Date_Exception 1095 */ 1096 public function add($date, $part = self::TIMESTAMP, $locale = null) 1097 { 1098 if (self::$_options['format_type'] == 'php') { 1099 $part = Zend_Locale_Format::convertPhpToIsoFormat($part); 1100 } 1101 1102 $this->_calculate('add', $date, $part, $locale); 1103 return $this; 1104 } 1105 1106 /** 1107 * Subtracts a date from another date. 1108 * This could be for example a RFC2822 date, the time, 1109 * the year or only the timestamp. There are about 50 different supported date parts. 1110 * For a complete list of supported datepart values look into the docu 1111 * Be aware: Adding -2 Months is not equal to Subtracting 2 Months !!! 1112 * 1113 * @param string|integer|array|Zend_Date $date Date or datepart to subtract 1114 * @param string $part OPTIONAL Part of the date to sub, if null the timestamp is subtracted 1115 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 1116 * @return Zend_Date Provides fluid interface 1117 * @throws Zend_Date_Exception 1118 */ 1119 public function sub($date, $part = self::TIMESTAMP, $locale = null) 1120 { 1121 if (self::$_options['format_type'] == 'php') { 1122 $part = Zend_Locale_Format::convertPhpToIsoFormat($part); 1123 } 1124 1125 $this->_calculate('sub', $date, $part, $locale); 1126 return $this; 1127 } 1128 1129 /** 1130 * Compares a date or datepart with the existing one. 1131 * Returns -1 if earlier, 0 if equal and 1 if later. 1132 * 1133 * @param string|integer|array|Zend_Date $date Date or datepart to compare with the date object 1134 * @param string $part OPTIONAL Part of the date to compare, if null the timestamp is subtracted 1135 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 1136 * @return integer 0 = equal, 1 = later, -1 = earlier 1137 * @throws Zend_Date_Exception 1138 */ 1139 public function compare($date, $part = self::TIMESTAMP, $locale = null) 1140 { 1141 if (self::$_options['format_type'] == 'php') { 1142 $part = Zend_Locale_Format::convertPhpToIsoFormat($part); 1143 } 1144 1145 $compare = $this->_calculate('cmp', $date, $part, $locale); 1146 1147 if ($compare > 0) { 1148 return 1; 1149 } else if ($compare < 0) { 1150 return -1; 1151 } 1152 return 0; 1153 } 1154 1155 /** 1156 * Returns a new instance of Zend_Date with the selected part copied. 1157 * To make an exact copy, use PHP's clone keyword. 1158 * For a complete list of supported date part values look into the docu. 1159 * If a date part is copied, all other date parts are set to standard values. 1160 * For example: If only YEAR is copied, the returned date object is equal to 1161 * 01-01-YEAR 00:00:00 (01-01-1970 00:00:00 is equal to timestamp 0) 1162 * If only HOUR is copied, the returned date object is equal to 1163 * 01-01-1970 HOUR:00:00 (so $this contains a timestamp equal to a timestamp of 0 plus HOUR). 1164 * 1165 * @param string $part Part of the date to compare, if null the timestamp is subtracted 1166 * @param string|Zend_Locale $locale OPTIONAL New object's locale. No adjustments to timezone are made. 1167 * @return Zend_Date New clone with requested part 1168 */ 1169 public function copyPart($part, $locale = null) 1170 { 1171 $clone = clone $this; // copy all instance variables 1172 $clone->setUnixTimestamp(0); // except the timestamp 1173 if ($locale != null) { 1174 $clone->setLocale($locale); // set an other locale if selected 1175 } 1176 $clone->set($this, $part); 1177 return $clone; 1178 } 1179 1180 /** 1181 * Internal function, returns the offset of a given timezone 1182 * 1183 * @param string $zone 1184 * @return integer 1185 */ 1186 public function getTimezoneFromString($zone) 1187 { 1188 if (is_array($zone)) { 1189 return $this->getTimezone(); 1190 } 1191 1192 if ($zone instanceof Zend_Date) { 1193 return $zone->getTimezone(); 1194 } 1195 1196 $match = array(); 1197 preg_match('/\dZ$/', $zone, $match); 1198 if (!empty($match)) { 1199 return "Etc/UTC"; 1200 } 1201 1202 preg_match('/([+-]\d{2}):{0,1}\d{2}/', $zone, $match); 1203 if (!empty($match) and ($match[count($match) - 1] <= 12) and ($match[count($match) - 1] >= -12)) { 1204 $zone = "Etc/GMT"; 1205 $zone .= ($match[count($match) - 1] < 0) ? "+" : "-"; 1206 $zone .= (int) abs($match[count($match) - 1]); 1207 return $zone; 1208 } 1209 1210 preg_match('/([[:alpha:]\/]{3,30})(?!.*([[:alpha:]\/]{3,30}))/', $zone, $match); 1211 try { 1212 if (!empty($match) and (!is_int($match[count($match) - 1]))) { 1213 $oldzone = $this->getTimezone(); 1214 $this->setTimezone($match[count($match) - 1]); 1215 $result = $this->getTimezone(); 1216 $this->setTimezone($oldzone); 1217 if ($result !== $oldzone) { 1218 return $match[count($match) - 1]; 1219 } 1220 } 1221 } catch (Exception $e) { 1222 // fall through 1223 } 1224 1225 return $this->getTimezone(); 1226 } 1227 1228 /** 1229 * Calculates the date or object 1230 * 1231 * @param string $calc Calculation to make 1232 * @param string|integer $date Date for calculation 1233 * @param string|integer $comp Second date for calculation 1234 * @param boolean|integer $dst Use dst correction if option is set 1235 * @return integer|string|Zend_Date new timestamp or Zend_Date depending on calculation 1236 */ 1237 private function _assign($calc, $date, $comp = 0, $dst = false) 1238 { 1239 switch ($calc) { 1240 case 'set' : 1241 if (!empty($comp)) { 1242 $this->setUnixTimestamp(call_user_func(Zend_Locale_Math::$sub, $this->getUnixTimestamp(), $comp)); 1243 } 1244 $this->setUnixTimestamp(call_user_func(Zend_Locale_Math::$add, $this->getUnixTimestamp(), $date)); 1245 $value = $this->getUnixTimestamp(); 1246 break; 1247 case 'add' : 1248 $this->setUnixTimestamp(call_user_func(Zend_Locale_Math::$add, $this->getUnixTimestamp(), $date)); 1249 $value = $this->getUnixTimestamp(); 1250 break; 1251 case 'sub' : 1252 $this->setUnixTimestamp(call_user_func(Zend_Locale_Math::$sub, $this->getUnixTimestamp(), $date)); 1253 $value = $this->getUnixTimestamp(); 1254 break; 1255 default : 1256 // cmp - compare 1257 return call_user_func(Zend_Locale_Math::$comp, $comp, $date); 1258 break; 1259 } 1260 1261 // dst-correction if 'fix_dst' = true and dst !== false but only for non UTC and non GMT 1262 if ((self::$_options['fix_dst'] === true) and ($dst !== false) and ($this->_dst === true)) { 1263 $hour = $this->toString(self::HOUR, 'iso'); 1264 if ($hour != $dst) { 1265 if (($dst == ($hour + 1)) or ($dst == ($hour - 23))) { 1266 $value += 3600; 1267 } else if (($dst == ($hour - 1)) or ($dst == ($hour + 23))) { 1268 $value -= 3600; 1269 } 1270 $this->setUnixTimestamp($value); 1271 } 1272 } 1273 return $this->getUnixTimestamp(); 1274 } 1275 1276 1277 /** 1278 * Calculates the date or object 1279 * 1280 * @param string $calc Calculation to make, one of: 'add'|'sub'|'cmp'|'copy'|'set' 1281 * @param string|integer|array|Zend_Date $date Date or datepart to calculate with 1282 * @param string $part Part of the date to calculate, if null the timestamp is used 1283 * @param string|Zend_Locale $locale Locale for parsing input 1284 * @return integer|string|Zend_Date new timestamp 1285 * @throws Zend_Date_Exception 1286 */ 1287 private function _calculate($calc, $date, $part, $locale) 1288 { 1289 if ($date === null) { 1290 require_once 'Zend/Date/Exception.php'; 1291 throw new Zend_Date_Exception('parameter $date must be set, null is not allowed'); 1292 } 1293 1294 if (($part !== null) && (strlen($part) !== 2) && (Zend_Locale::isLocale($part, null, false))) { 1295 $locale = $part; 1296 $part = null; 1297 } 1298 1299 if ($locale === null) { 1300 $locale = $this->getLocale(); 1301 } 1302 1303 $locale = (string) $locale; 1304 1305 // Create date parts 1306 $year = $this->toString(self::YEAR, 'iso'); 1307 $month = $this->toString(self::MONTH_SHORT, 'iso'); 1308 $day = $this->toString(self::DAY_SHORT, 'iso'); 1309 $hour = $this->toString(self::HOUR_SHORT, 'iso'); 1310 $minute = $this->toString(self::MINUTE_SHORT, 'iso'); 1311 $second = $this->toString(self::SECOND_SHORT, 'iso'); 1312 // If object extract value 1313 if ($date instanceof Zend_Date) { 1314 $date = $date->toString($part, 'iso', $locale); 1315 } 1316 1317 if (is_array($date) === true) { 1318 if (empty($part) === false) { 1319 switch($part) { 1320 // Fall through 1321 case self::DAY: 1322 case self::DAY_SHORT: 1323 if (isset($date['day']) === true) { 1324 $date = $date['day']; 1325 } 1326 break; 1327 // Fall through 1328 case self::WEEKDAY_SHORT: 1329 case self::WEEKDAY: 1330 case self::WEEKDAY_8601: 1331 case self::WEEKDAY_DIGIT: 1332 case self::WEEKDAY_NARROW: 1333 case self::WEEKDAY_NAME: 1334 if (isset($date['weekday']) === true) { 1335 $date = $date['weekday']; 1336 $part = self::WEEKDAY_DIGIT; 1337 } 1338 break; 1339 case self::DAY_OF_YEAR: 1340 if (isset($date['day_of_year']) === true) { 1341 $date = $date['day_of_year']; 1342 } 1343 break; 1344 // Fall through 1345 case self::MONTH: 1346 case self::MONTH_SHORT: 1347 case self::MONTH_NAME: 1348 case self::MONTH_NAME_SHORT: 1349 case self::MONTH_NAME_NARROW: 1350 if (isset($date['month']) === true) { 1351 $date = $date['month']; 1352 } 1353 break; 1354 // Fall through 1355 case self::YEAR: 1356 case self::YEAR_SHORT: 1357 case self::YEAR_8601: 1358 case self::YEAR_SHORT_8601: 1359 if (isset($date['year']) === true) { 1360 $date = $date['year']; 1361 } 1362 break; 1363 // Fall through 1364 case self::HOUR: 1365 case self::HOUR_AM: 1366 case self::HOUR_SHORT: 1367 case self::HOUR_SHORT_AM: 1368 if (isset($date['hour']) === true) { 1369 $date = $date['hour']; 1370 } 1371 break; 1372 // Fall through 1373 case self::MINUTE: 1374 case self::MINUTE_SHORT: 1375 if (isset($date['minute']) === true) { 1376 $date = $date['minute']; 1377 } 1378 break; 1379 // Fall through 1380 case self::SECOND: 1381 case self::SECOND_SHORT: 1382 if (isset($date['second']) === true) { 1383 $date = $date['second']; 1384 } 1385 break; 1386 // Fall through 1387 case self::TIMEZONE: 1388 case self::TIMEZONE_NAME: 1389 if (isset($date['timezone']) === true) { 1390 $date = $date['timezone']; 1391 } 1392 break; 1393 case self::TIMESTAMP: 1394 if (isset($date['timestamp']) === true) { 1395 $date = $date['timestamp']; 1396 } 1397 break; 1398 case self::WEEK: 1399 if (isset($date['week']) === true) { 1400 $date = $date['week']; 1401 } 1402 break; 1403 case self::TIMEZONE_SECS: 1404 if (isset($date['gmtsecs']) === true) { 1405 $date = $date['gmtsecs']; 1406 } 1407 break; 1408 default: 1409 require_once 'Zend/Date/Exception.php'; 1410 throw new Zend_Date_Exception("datepart for part ($part) not found in array"); 1411 break; 1412 } 1413 } else { 1414 $hours = 0; 1415 if (isset($date['hour']) === true) { 1416 $hours = $date['hour']; 1417 } 1418 $minutes = 0; 1419 if (isset($date['minute']) === true) { 1420 $minutes = $date['minute']; 1421 } 1422 $seconds = 0; 1423 if (isset($date['second']) === true) { 1424 $seconds = $date['second']; 1425 } 1426 $months = 0; 1427 if (isset($date['month']) === true) { 1428 $months = $date['month']; 1429 } 1430 $days = 0; 1431 if (isset($date['day']) === true) { 1432 $days = $date['day']; 1433 } 1434 $years = 0; 1435 if (isset($date['year']) === true) { 1436 $years = $date['year']; 1437 } 1438 return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, $months, $days, $years, true), 1439 $this->mktime($hour, $minute, $second, $month, $day, $year, true), $hour); 1440 } 1441 } 1442 1443 // $date as object, part of foreign date as own date 1444 switch($part) { 1445 1446 // day formats 1447 case self::DAY: 1448 if (is_numeric($date)) { 1449 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true), 1450 $this->mktime(0, 0, 0, 1, 1 + intval($day), 1970, true), $hour); 1451 } 1452 1453 require_once 'Zend/Date/Exception.php'; 1454 throw new Zend_Date_Exception("invalid date ($date) operand, day expected", 0, null, $date); 1455 break; 1456 1457 case self::WEEKDAY_SHORT: 1458 $daylist = Zend_Locale_Data::getList($locale, 'day'); 1459 $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); 1460 $cnt = 0; 1461 1462 foreach ($daylist as $key => $value) { 1463 if (strtoupper(iconv_substr($value, 0, 3, 'UTF-8')) == strtoupper($date)) { 1464 $found = $cnt; 1465 break; 1466 } 1467 ++$cnt; 1468 } 1469 1470 // Weekday found 1471 if ($cnt < 7) { 1472 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), 1473 $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); 1474 } 1475 1476 // Weekday not found 1477 require_once 'Zend/Date/Exception.php'; 1478 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); 1479 break; 1480 1481 case self::DAY_SHORT: 1482 if (is_numeric($date)) { 1483 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true), 1484 $this->mktime(0, 0, 0, 1, 1 + intval($day), 1970, true), $hour); 1485 } 1486 1487 require_once 'Zend/Date/Exception.php'; 1488 throw new Zend_Date_Exception("invalid date ($date) operand, day expected", 0, null, $date); 1489 break; 1490 1491 case self::WEEKDAY: 1492 $daylist = Zend_Locale_Data::getList($locale, 'day'); 1493 $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); 1494 $cnt = 0; 1495 1496 foreach ($daylist as $key => $value) { 1497 if (strtoupper($value) == strtoupper($date)) { 1498 $found = $cnt; 1499 break; 1500 } 1501 ++$cnt; 1502 } 1503 1504 // Weekday found 1505 if ($cnt < 7) { 1506 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), 1507 $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); 1508 } 1509 1510 // Weekday not found 1511 require_once 'Zend/Date/Exception.php'; 1512 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); 1513 break; 1514 1515 case self::WEEKDAY_8601: 1516 $weekday = (int) $this->toString(self::WEEKDAY_8601, 'iso', $locale); 1517 if ((intval($date) > 0) and (intval($date) < 8)) { 1518 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true), 1519 $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); 1520 } 1521 1522 // Weekday not found 1523 require_once 'Zend/Date/Exception.php'; 1524 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); 1525 break; 1526 1527 case self::DAY_SUFFIX: 1528 require_once 'Zend/Date/Exception.php'; 1529 throw new Zend_Date_Exception('day suffix not supported', 0, null, $date); 1530 break; 1531 1532 case self::WEEKDAY_DIGIT: 1533 $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); 1534 if (is_numeric($date) and (intval($date) >= 0) and (intval($date) < 7)) { 1535 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $date, 1970, true), 1536 $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); 1537 } 1538 1539 // Weekday not found 1540 require_once 'Zend/Date/Exception.php'; 1541 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); 1542 break; 1543 1544 case self::DAY_OF_YEAR: 1545 if (is_numeric($date)) { 1546 if (($calc == 'add') || ($calc == 'sub')) { 1547 $year = 1970; 1548 ++$date; 1549 ++$day; 1550 } 1551 1552 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, $date, $year, true), 1553 $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); 1554 } 1555 1556 require_once 'Zend/Date/Exception.php'; 1557 throw new Zend_Date_Exception("invalid date ($date) operand, day expected", 0, null, $date); 1558 break; 1559 1560 case self::WEEKDAY_NARROW: 1561 $daylist = Zend_Locale_Data::getList($locale, 'day', array('gregorian', 'format', 'abbreviated')); 1562 $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); 1563 $cnt = 0; 1564 foreach ($daylist as $key => $value) { 1565 if (strtoupper(iconv_substr($value, 0, 1, 'UTF-8')) == strtoupper($date)) { 1566 $found = $cnt; 1567 break; 1568 } 1569 ++$cnt; 1570 } 1571 1572 // Weekday found 1573 if ($cnt < 7) { 1574 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), 1575 $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); 1576 } 1577 1578 // Weekday not found 1579 require_once 'Zend/Date/Exception.php'; 1580 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); 1581 break; 1582 1583 case self::WEEKDAY_NAME: 1584 $daylist = Zend_Locale_Data::getList($locale, 'day', array('gregorian', 'format', 'abbreviated')); 1585 $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale); 1586 $cnt = 0; 1587 foreach ($daylist as $key => $value) { 1588 if (strtoupper($value) == strtoupper($date)) { 1589 $found = $cnt; 1590 break; 1591 } 1592 ++$cnt; 1593 } 1594 1595 // Weekday found 1596 if ($cnt < 7) { 1597 return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true), 1598 $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour); 1599 } 1600 1601 // Weekday not found 1602 require_once 'Zend/Date/Exception.php'; 1603 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date); 1604 break; 1605 1606 // week formats 1607 case self::WEEK: 1608 if (is_numeric($date)) { 1609 $week = (int) $this->toString(self::WEEK, 'iso', $locale); 1610 return $this->_assign($calc, parent::mktime(0, 0, 0, 1, 1 + ($date * 7), 1970, true), 1611 parent::mktime(0, 0, 0, 1, 1 + ($week * 7), 1970, true), $hour); 1612 } 1613 1614 require_once 'Zend/Date/Exception.php'; 1615 throw new Zend_Date_Exception("invalid date ($date) operand, week expected", 0, null, $date); 1616 break; 1617 1618 // month formats 1619 case self::MONTH_NAME: 1620 $monthlist = Zend_Locale_Data::getList($locale, 'month'); 1621 $cnt = 0; 1622 foreach ($monthlist as $key => $value) { 1623 if (strtoupper($value) == strtoupper($date)) { 1624 $found = $key; 1625 break; 1626 } 1627 ++$cnt; 1628 } 1629 $date = array_search($date, $monthlist); 1630 1631 // Monthname found 1632 if ($cnt < 12) { 1633 $fixday = 0; 1634 if ($calc == 'add') { 1635 $date += $found; 1636 $calc = 'set'; 1637 if (self::$_options['extend_month'] == false) { 1638 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1639 if ($parts['mday'] != $day) { 1640 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1641 } 1642 } 1643 } else if ($calc == 'sub') { 1644 $date = $month - $found; 1645 $calc = 'set'; 1646 if (self::$_options['extend_month'] == false) { 1647 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1648 if ($parts['mday'] != $day) { 1649 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1650 } 1651 } 1652 } 1653 return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), 1654 $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); 1655 } 1656 1657 // Monthname not found 1658 require_once 'Zend/Date/Exception.php'; 1659 throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date); 1660 break; 1661 1662 case self::MONTH: 1663 if (is_numeric($date)) { 1664 $fixday = 0; 1665 if ($calc == 'add') { 1666 $date += $month; 1667 $calc = 'set'; 1668 if (self::$_options['extend_month'] == false) { 1669 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1670 if ($parts['mday'] != $day) { 1671 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1672 } 1673 } 1674 } else if ($calc == 'sub') { 1675 $date = $month - $date; 1676 $calc = 'set'; 1677 if (self::$_options['extend_month'] == false) { 1678 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1679 if ($parts['mday'] != $day) { 1680 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1681 } 1682 } 1683 } 1684 return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), 1685 $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); 1686 } 1687 1688 require_once 'Zend/Date/Exception.php'; 1689 throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date); 1690 break; 1691 1692 case self::MONTH_NAME_SHORT: 1693 $monthlist = Zend_Locale_Data::getList($locale, 'month', array('gregorian', 'format', 'abbreviated')); 1694 $cnt = 0; 1695 foreach ($monthlist as $key => $value) { 1696 if (strtoupper($value) == strtoupper($date)) { 1697 $found = $key; 1698 break; 1699 } 1700 ++$cnt; 1701 } 1702 $date = array_search($date, $monthlist); 1703 1704 // Monthname found 1705 if ($cnt < 12) { 1706 $fixday = 0; 1707 if ($calc == 'add') { 1708 $date += $found; 1709 $calc = 'set'; 1710 if (self::$_options['extend_month'] === false) { 1711 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1712 if ($parts['mday'] != $day) { 1713 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1714 } 1715 } 1716 } else if ($calc == 'sub') { 1717 $date = $month - $found; 1718 $calc = 'set'; 1719 if (self::$_options['extend_month'] === false) { 1720 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1721 if ($parts['mday'] != $day) { 1722 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1723 } 1724 } 1725 } 1726 return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), 1727 $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); 1728 } 1729 1730 // Monthname not found 1731 require_once 'Zend/Date/Exception.php'; 1732 throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date); 1733 break; 1734 1735 case self::MONTH_SHORT: 1736 if (is_numeric($date) === true) { 1737 $fixday = 0; 1738 if ($calc === 'add') { 1739 $date += $month; 1740 $calc = 'set'; 1741 if (self::$_options['extend_month'] === false) { 1742 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1743 if ($parts['mday'] != $day) { 1744 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1745 } 1746 } 1747 } else if ($calc === 'sub') { 1748 $date = $month - $date; 1749 $calc = 'set'; 1750 if (self::$_options['extend_month'] === false) { 1751 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1752 if ($parts['mday'] != $day) { 1753 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1754 } 1755 } 1756 } 1757 1758 return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), 1759 $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); 1760 } 1761 1762 require_once 'Zend/Date/Exception.php'; 1763 throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date); 1764 break; 1765 1766 case self::MONTH_DAYS: 1767 require_once 'Zend/Date/Exception.php'; 1768 throw new Zend_Date_Exception('month days not supported', 0, null, $date); 1769 break; 1770 1771 case self::MONTH_NAME_NARROW: 1772 $monthlist = Zend_Locale_Data::getList($locale, 'month', array('gregorian', 'stand-alone', 'narrow')); 1773 $cnt = 0; 1774 foreach ($monthlist as $key => $value) { 1775 if (strtoupper($value) === strtoupper($date)) { 1776 $found = $key; 1777 break; 1778 } 1779 ++$cnt; 1780 } 1781 $date = array_search($date, $monthlist); 1782 1783 // Monthname found 1784 if ($cnt < 12) { 1785 $fixday = 0; 1786 if ($calc === 'add') { 1787 $date += $found; 1788 $calc = 'set'; 1789 if (self::$_options['extend_month'] === false) { 1790 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1791 if ($parts['mday'] != $day) { 1792 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1793 } 1794 } 1795 } else if ($calc === 'sub') { 1796 $date = $month - $found; 1797 $calc = 'set'; 1798 if (self::$_options['extend_month'] === false) { 1799 $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); 1800 if ($parts['mday'] != $day) { 1801 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); 1802 } 1803 } 1804 } 1805 return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), 1806 $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); 1807 } 1808 1809 // Monthname not found 1810 require_once 'Zend/Date/Exception.php'; 1811 throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date); 1812 break; 1813 1814 // year formats 1815 case self::LEAPYEAR: 1816 require_once 'Zend/Date/Exception.php'; 1817 throw new Zend_Date_Exception('leap year not supported', 0, null, $date); 1818 break; 1819 1820 case self::YEAR_8601: 1821 if (is_numeric($date)) { 1822 if ($calc === 'add') { 1823 $date += $year; 1824 $calc = 'set'; 1825 } else if ($calc === 'sub') { 1826 $date = $year - $date; 1827 $calc = 'set'; 1828 } 1829 1830 return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, intval($date), true), 1831 $this->mktime(0, 0, 0, $month, $day, $year, true), false); 1832 } 1833 1834 require_once 'Zend/Date/Exception.php'; 1835 throw new Zend_Date_Exception("invalid date ($date) operand, year expected", 0, null, $date); 1836 break; 1837 1838 case self::YEAR: 1839 if (is_numeric($date)) { 1840 if ($calc === 'add') { 1841 $date += $year; 1842 $calc = 'set'; 1843 } else if ($calc === 'sub') { 1844 $date = $year - $date; 1845 $calc = 'set'; 1846 } 1847 1848 return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, intval($date), true), 1849 $this->mktime(0, 0, 0, $month, $day, $year, true), false); 1850 } 1851 1852 require_once 'Zend/Date/Exception.php'; 1853 throw new Zend_Date_Exception("invalid date ($date) operand, year expected", 0, null, $date); 1854 break; 1855 1856 case self::YEAR_SHORT: 1857 if (is_numeric($date)) { 1858 $date = intval($date); 1859 if (($calc == 'set') || ($calc == 'cmp')) { 1860 $date = self::getFullYear($date); 1861 } 1862 if ($calc === 'add') { 1863 $date += $year; 1864 $calc = 'set'; 1865 } else if ($calc === 'sub') { 1866 $date = $year - $date; 1867 $calc = 'set'; 1868 } 1869 1870 return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, $date, true), 1871 $this->mktime(0, 0, 0, $month, $day, $year, true), false); 1872 } 1873 1874 require_once 'Zend/Date/Exception.php'; 1875 throw new Zend_Date_Exception("invalid date ($date) operand, year expected", 0, null, $date); 1876 break; 1877 1878 case self::YEAR_SHORT_8601: 1879 if (is_numeric($date)) { 1880 $date = intval($date); 1881 if (($calc === 'set') || ($calc === 'cmp')) { 1882 $date = self::getFullYear($date); 1883 } 1884 if ($calc === 'add') { 1885 $date += $year; 1886 $calc = 'set'; 1887 } else if ($calc === 'sub') { 1888 $date = $year - $date; 1889 $calc = 'set'; 1890 } 1891 1892 return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, $date, true), 1893 $this->mktime(0, 0, 0, $month, $day, $year, true), false); 1894 } 1895 1896 require_once 'Zend/Date/Exception.php'; 1897 throw new Zend_Date_Exception("invalid date ($date) operand, year expected", 0, null, $date); 1898 break; 1899 1900 // time formats 1901 case self::MERIDIEM: 1902 require_once 'Zend/Date/Exception.php'; 1903 throw new Zend_Date_Exception('meridiem not supported', 0, null, $date); 1904 break; 1905 1906 case self::SWATCH: 1907 if (is_numeric($date)) { 1908 $rest = intval($date); 1909 $hours = floor($rest * 24 / 1000); 1910 $rest = $rest - ($hours * 1000 / 24); 1911 $minutes = floor($rest * 1440 / 1000); 1912 $rest = $rest - ($minutes * 1000 / 1440); 1913 $seconds = floor($rest * 86400 / 1000); 1914 return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, 1, 1, 1970, true), 1915 $this->mktime($hour, $minute, $second, 1, 1, 1970, true), false); 1916 } 1917 1918 require_once 'Zend/Date/Exception.php'; 1919 throw new Zend_Date_Exception("invalid date ($date) operand, swatchstamp expected", 0, null, $date); 1920 break; 1921 1922 case self::HOUR_SHORT_AM: 1923 if (is_numeric($date)) { 1924 return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), 1925 $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); 1926 } 1927 1928 require_once 'Zend/Date/Exception.php'; 1929 throw new Zend_Date_Exception("invalid date ($date) operand, hour expected", 0, null, $date); 1930 break; 1931 1932 case self::HOUR_SHORT: 1933 if (is_numeric($date)) { 1934 return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), 1935 $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); 1936 } 1937 1938 require_once 'Zend/Date/Exception.php'; 1939 throw new Zend_Date_Exception("invalid date ($date) operand, hour expected", 0, null, $date); 1940 break; 1941 1942 case self::HOUR_AM: 1943 if (is_numeric($date)) { 1944 return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), 1945 $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); 1946 } 1947 1948 require_once 'Zend/Date/Exception.php'; 1949 throw new Zend_Date_Exception("invalid date ($date) operand, hour expected", 0, null, $date); 1950 break; 1951 1952 case self::HOUR: 1953 if (is_numeric($date)) { 1954 return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true), 1955 $this->mktime($hour, 0, 0, 1, 1, 1970, true), false); 1956 } 1957 1958 require_once 'Zend/Date/Exception.php'; 1959 throw new Zend_Date_Exception("invalid date ($date) operand, hour expected", 0, null, $date); 1960 break; 1961 1962 case self::MINUTE: 1963 if (is_numeric($date)) { 1964 return $this->_assign($calc, $this->mktime(0, intval($date), 0, 1, 1, 1970, true), 1965 $this->mktime(0, $minute, 0, 1, 1, 1970, true), false); 1966 } 1967 1968 require_once 'Zend/Date/Exception.php'; 1969 throw new Zend_Date_Exception("invalid date ($date) operand, minute expected", 0, null, $date); 1970 break; 1971 1972 case self::SECOND: 1973 if (is_numeric($date)) { 1974 return $this->_assign($calc, $this->mktime(0, 0, intval($date), 1, 1, 1970, true), 1975 $this->mktime(0, 0, $second, 1, 1, 1970, true), false); 1976 } 1977 1978 require_once 'Zend/Date/Exception.php'; 1979 throw new Zend_Date_Exception("invalid date ($date) operand, second expected", 0, null, $date); 1980 break; 1981 1982 case self::MILLISECOND: 1983 if (is_numeric($date)) { 1984 switch($calc) { 1985 case 'set' : 1986 return $this->setMillisecond($date); 1987 break; 1988 case 'add' : 1989 return $this->addMillisecond($date); 1990 break; 1991 case 'sub' : 1992 return $this->subMillisecond($date); 1993 break; 1994 } 1995 1996 return $this->compareMillisecond($date); 1997 } 1998 1999 require_once 'Zend/Date/Exception.php'; 2000 throw new Zend_Date_Exception("invalid date ($date) operand, milliseconds expected", 0, null, $date); 2001 break; 2002 2003 case self::MINUTE_SHORT: 2004 if (is_numeric($date)) { 2005 return $this->_assign($calc, $this->mktime(0, intval($date), 0, 1, 1, 1970, true), 2006 $this->mktime(0, $minute, 0, 1, 1, 1970, true), false); 2007 } 2008 2009 require_once 'Zend/Date/Exception.php'; 2010 throw new Zend_Date_Exception("invalid date ($date) operand, minute expected", 0, null, $date); 2011 break; 2012 2013 case self::SECOND_SHORT: 2014 if (is_numeric($date)) { 2015 return $this->_assign($calc, $this->mktime(0, 0, intval($date), 1, 1, 1970, true), 2016 $this->mktime(0, 0, $second, 1, 1, 1970, true), false); 2017 } 2018 2019 require_once 'Zend/Date/Exception.php'; 2020 throw new Zend_Date_Exception("invalid date ($date) operand, second expected", 0, null, $date); 2021 break; 2022 2023 // timezone formats 2024 // break intentionally omitted 2025 case self::TIMEZONE_NAME: 2026 case self::TIMEZONE: 2027 case self::TIMEZONE_SECS: 2028 require_once 'Zend/Date/Exception.php'; 2029 throw new Zend_Date_Exception('timezone not supported', 0, null, $date); 2030 break; 2031 2032 case self::DAYLIGHT: 2033 require_once 'Zend/Date/Exception.php'; 2034 throw new Zend_Date_Exception('daylight not supported', 0, null, $date); 2035 break; 2036 2037 case self::GMT_DIFF: 2038 case self::GMT_DIFF_SEP: 2039 require_once 'Zend/Date/Exception.php'; 2040 throw new Zend_Date_Exception('gmtdiff not supported', 0, null, $date); 2041 break; 2042 2043 // date strings 2044 case self::ISO_8601: 2045 // (-)YYYY-MM-dd 2046 preg_match('/^(-{0,1}\d{4})-(\d{2})-(\d{2})/', $date, $datematch); 2047 // (-)YY-MM-dd 2048 if (empty($datematch)) { 2049 preg_match('/^(-{0,1}\d{2})-(\d{2})-(\d{2})/', $date, $datematch); 2050 } 2051 // (-)YYYYMMdd 2052 if (empty($datematch)) { 2053 preg_match('/^(-{0,1}\d{4})(\d{2})(\d{2})/', $date, $datematch); 2054 } 2055 // (-)YYMMdd 2056 if (empty($datematch)) { 2057 preg_match('/^(-{0,1}\d{2})(\d{2})(\d{2})/', $date, $datematch); 2058 } 2059 $tmpdate = $date; 2060 if (!empty($datematch)) { 2061 $dateMatchCharCount = iconv_strlen($datematch[0], 'UTF-8'); 2062 $tmpdate = iconv_substr($date, 2063 $dateMatchCharCount, 2064 iconv_strlen($date, 'UTF-8') - $dateMatchCharCount, 2065 'UTF-8'); 2066 } 2067 // (T)hh:mm:ss 2068 preg_match('/[T,\s]{0,1}(\d{2}):(\d{2}):(\d{2})/', $tmpdate, $timematch); 2069 if (empty($timematch)) { 2070 preg_match('/[T,\s]{0,1}(\d{2})(\d{2})(\d{2})/', $tmpdate, $timematch); 2071 } 2072 if (empty($datematch) and empty($timematch)) { 2073 require_once 'Zend/Date/Exception.php'; 2074 throw new Zend_Date_Exception("unsupported ISO8601 format ($date)", 0, null, $date); 2075 } 2076 if (!empty($timematch)) { 2077 $timeMatchCharCount = iconv_strlen($timematch[0], 'UTF-8'); 2078 $tmpdate = iconv_substr($tmpdate, 2079 $timeMatchCharCount, 2080 iconv_strlen($tmpdate, 'UTF-8') - $timeMatchCharCount, 2081 'UTF-8'); 2082 } 2083 if (empty($datematch)) { 2084 $datematch[1] = 1970; 2085 $datematch[2] = 1; 2086 $datematch[3] = 1; 2087 } else if (iconv_strlen($datematch[1], 'UTF-8') == 2) { 2088 $datematch[1] = self::getFullYear($datematch[1]); 2089 } 2090 if (empty($timematch)) { 2091 $timematch[1] = 0; 2092 $timematch[2] = 0; 2093 $timematch[3] = 0; 2094 } 2095 2096 if (($calc == 'set') || ($calc == 'cmp')) { 2097 --$datematch[2]; 2098 --$month; 2099 --$datematch[3]; 2100 --$day; 2101 $datematch[1] -= 1970; 2102 $year -= 1970; 2103 } 2104 return $this->_assign($calc, $this->mktime($timematch[1], $timematch[2], $timematch[3], 1 + $datematch[2], 1 + $datematch[3], 1970 + $datematch[1], false), 2105 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, false), false); 2106 break; 2107 2108 case self::RFC_2822: 2109 $result = preg_match('/^\w{3},\s(\d{1,2})\s(\w{3})\s(\d{4})\s(\d{2}):(\d{2}):{0,1}(\d{0,2})\s([+-]{1}\d{4})$/', $date, $match); 2110 if (!$result) { 2111 require_once 'Zend/Date/Exception.php'; 2112 throw new Zend_Date_Exception("no RFC 2822 format ($date)", 0, null, $date); 2113 } 2114 2115 $months = $this->_getDigitFromName($match[2]); 2116 2117 if (($calc == 'set') || ($calc == 'cmp')) { 2118 --$months; 2119 --$month; 2120 --$match[1]; 2121 --$day; 2122 $match[3] -= 1970; 2123 $year -= 1970; 2124 } 2125 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], false), 2126 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, false), false); 2127 break; 2128 2129 case self::TIMESTAMP: 2130 if (is_numeric($date)) { 2131 return $this->_assign($calc, $date, $this->getUnixTimestamp()); 2132 } 2133 2134 require_once 'Zend/Date/Exception.php'; 2135 throw new Zend_Date_Exception("invalid date ($date) operand, timestamp expected", 0, null, $date); 2136 break; 2137 2138 // additional formats 2139 // break intentionally omitted 2140 case self::ERA: 2141 case self::ERA_NAME: 2142 require_once 'Zend/Date/Exception.php'; 2143 throw new Zend_Date_Exception('era not supported', 0, null, $date); 2144 break; 2145 2146 case self::DATES: 2147 try { 2148 $parsed = Zend_Locale_Format::getDate($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true)); 2149 2150 if (($calc == 'set') || ($calc == 'cmp')) { 2151 --$parsed['month']; 2152 --$month; 2153 --$parsed['day']; 2154 --$day; 2155 $parsed['year'] -= 1970; 2156 $year -= 1970; 2157 } 2158 2159 return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2160 $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2161 } catch (Zend_Locale_Exception $e) { 2162 require_once 'Zend/Date/Exception.php'; 2163 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2164 } 2165 break; 2166 2167 case self::DATE_FULL: 2168 try { 2169 $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'full')); 2170 $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2171 2172 if (($calc == 'set') || ($calc == 'cmp')) { 2173 --$parsed['month']; 2174 --$month; 2175 --$parsed['day']; 2176 --$day; 2177 $parsed['year'] -= 1970; 2178 $year -= 1970; 2179 } 2180 return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2181 $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2182 } catch (Zend_Locale_Exception $e) { 2183 require_once 'Zend/Date/Exception.php'; 2184 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2185 } 2186 break; 2187 2188 case self::DATE_LONG: 2189 try { 2190 $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'long')); 2191 $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2192 2193 if (($calc == 'set') || ($calc == 'cmp')){ 2194 --$parsed['month']; 2195 --$month; 2196 --$parsed['day']; 2197 --$day; 2198 $parsed['year'] -= 1970; 2199 $year -= 1970; 2200 } 2201 return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2202 $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2203 } catch (Zend_Locale_Exception $e) { 2204 require_once 'Zend/Date/Exception.php'; 2205 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2206 } 2207 break; 2208 2209 case self::DATE_MEDIUM: 2210 try { 2211 $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'medium')); 2212 $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2213 2214 if (($calc == 'set') || ($calc == 'cmp')) { 2215 --$parsed['month']; 2216 --$month; 2217 --$parsed['day']; 2218 --$day; 2219 $parsed['year'] -= 1970; 2220 $year -= 1970; 2221 } 2222 return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2223 $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2224 } catch (Zend_Locale_Exception $e) { 2225 require_once 'Zend/Date/Exception.php'; 2226 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2227 } 2228 break; 2229 2230 case self::DATE_SHORT: 2231 try { 2232 $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'short')); 2233 $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2234 2235 $parsed['year'] = self::getFullYear($parsed['year']); 2236 2237 if (($calc == 'set') || ($calc == 'cmp')) { 2238 --$parsed['month']; 2239 --$month; 2240 --$parsed['day']; 2241 --$day; 2242 $parsed['year'] -= 1970; 2243 $year -= 1970; 2244 } 2245 return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2246 $this->mktime(0, 0, 0, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2247 } catch (Zend_Locale_Exception $e) { 2248 require_once 'Zend/Date/Exception.php'; 2249 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2250 } 2251 break; 2252 2253 case self::TIMES: 2254 try { 2255 if ($calc != 'set') { 2256 $month = 1; 2257 $day = 1; 2258 $year = 1970; 2259 } 2260 $parsed = Zend_Locale_Format::getTime($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true)); 2261 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), 2262 $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); 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::TIME_FULL: 2270 try { 2271 $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'full')); 2272 $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2273 if ($calc != 'set') { 2274 $month = 1; 2275 $day = 1; 2276 $year = 1970; 2277 } 2278 2279 if (!isset($parsed['second'])) { 2280 $parsed['second'] = 0; 2281 } 2282 2283 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), 2284 $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); 2285 } catch (Zend_Locale_Exception $e) { 2286 require_once 'Zend/Date/Exception.php'; 2287 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2288 } 2289 break; 2290 2291 case self::TIME_LONG: 2292 try { 2293 $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'long')); 2294 $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2295 if ($calc != 'set') { 2296 $month = 1; 2297 $day = 1; 2298 $year = 1970; 2299 } 2300 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), 2301 $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); 2302 } catch (Zend_Locale_Exception $e) { 2303 require_once 'Zend/Date/Exception.php'; 2304 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2305 } 2306 break; 2307 2308 case self::TIME_MEDIUM: 2309 try { 2310 $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'medium')); 2311 $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2312 if ($calc != 'set') { 2313 $month = 1; 2314 $day = 1; 2315 $year = 1970; 2316 } 2317 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), 2318 $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); 2319 } catch (Zend_Locale_Exception $e) { 2320 require_once 'Zend/Date/Exception.php'; 2321 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2322 } 2323 break; 2324 2325 case self::TIME_SHORT: 2326 try { 2327 $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'short')); 2328 $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2329 if ($calc != 'set') { 2330 $month = 1; 2331 $day = 1; 2332 $year = 1970; 2333 } 2334 2335 if (!isset($parsed['second'])) { 2336 $parsed['second'] = 0; 2337 } 2338 2339 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true), 2340 $this->mktime($hour, $minute, $second, $month, $day, $year, true), false); 2341 } catch (Zend_Locale_Exception $e) { 2342 require_once 'Zend/Date/Exception.php'; 2343 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2344 } 2345 break; 2346 2347 case self::DATETIME: 2348 try { 2349 $parsed = Zend_Locale_Format::getDateTime($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true)); 2350 if (($calc == 'set') || ($calc == 'cmp')) { 2351 --$parsed['month']; 2352 --$month; 2353 --$parsed['day']; 2354 --$day; 2355 $parsed['year'] -= 1970; 2356 $year -= 1970; 2357 } 2358 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2359 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2360 } catch (Zend_Locale_Exception $e) { 2361 require_once 'Zend/Date/Exception.php'; 2362 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2363 } 2364 break; 2365 2366 case self::DATETIME_FULL: 2367 try { 2368 $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'full')); 2369 $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2370 2371 if (($calc == 'set') || ($calc == 'cmp')) { 2372 --$parsed['month']; 2373 --$month; 2374 --$parsed['day']; 2375 --$day; 2376 $parsed['year'] -= 1970; 2377 $year -= 1970; 2378 } 2379 2380 if (!isset($parsed['second'])) { 2381 $parsed['second'] = 0; 2382 } 2383 2384 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2385 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2386 } catch (Zend_Locale_Exception $e) { 2387 require_once 'Zend/Date/Exception.php'; 2388 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2389 } 2390 break; 2391 2392 case self::DATETIME_LONG: 2393 try { 2394 $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'long')); 2395 $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2396 2397 if (($calc == 'set') || ($calc == 'cmp')){ 2398 --$parsed['month']; 2399 --$month; 2400 --$parsed['day']; 2401 --$day; 2402 $parsed['year'] -= 1970; 2403 $year -= 1970; 2404 } 2405 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2406 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2407 } catch (Zend_Locale_Exception $e) { 2408 require_once 'Zend/Date/Exception.php'; 2409 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2410 } 2411 break; 2412 2413 case self::DATETIME_MEDIUM: 2414 try { 2415 $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'medium')); 2416 $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2417 if (($calc == 'set') || ($calc == 'cmp')) { 2418 --$parsed['month']; 2419 --$month; 2420 --$parsed['day']; 2421 --$day; 2422 $parsed['year'] -= 1970; 2423 $year -= 1970; 2424 } 2425 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2426 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2427 } catch (Zend_Locale_Exception $e) { 2428 require_once 'Zend/Date/Exception.php'; 2429 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2430 } 2431 break; 2432 2433 case self::DATETIME_SHORT: 2434 try { 2435 $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'short')); 2436 $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale)); 2437 2438 $parsed['year'] = self::getFullYear($parsed['year']); 2439 2440 if (($calc == 'set') || ($calc == 'cmp')) { 2441 --$parsed['month']; 2442 --$month; 2443 --$parsed['day']; 2444 --$day; 2445 $parsed['year'] -= 1970; 2446 $year -= 1970; 2447 } 2448 2449 if (!isset($parsed['second'])) { 2450 $parsed['second'] = 0; 2451 } 2452 2453 return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true), 2454 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), $hour); 2455 } catch (Zend_Locale_Exception $e) { 2456 require_once 'Zend/Date/Exception.php'; 2457 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2458 } 2459 break; 2460 2461 // ATOM and RFC_3339 are identical 2462 case self::ATOM: 2463 case self::RFC_3339: 2464 $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); 2465 if (!$result) { 2466 require_once 'Zend/Date/Exception.php'; 2467 throw new Zend_Date_Exception("invalid date ($date) operand, ATOM format expected", 0, null, $date); 2468 } 2469 2470 if (($calc == 'set') || ($calc == 'cmp')) { 2471 --$match[2]; 2472 --$month; 2473 --$match[3]; 2474 --$day; 2475 $match[1] -= 1970; 2476 $year -= 1970; 2477 } 2478 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $match[2], 1 + $match[3], 1970 + $match[1], true), 2479 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); 2480 break; 2481 2482 case self::COOKIE: 2483 $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); 2484 if (!$result) { 2485 require_once 'Zend/Date/Exception.php'; 2486 throw new Zend_Date_Exception("invalid date ($date) operand, COOKIE format expected", 0, null, $date); 2487 } 2488 $matchStartPos = iconv_strpos($match[0], ' ', 0, 'UTF-8') + 1; 2489 $match[0] = iconv_substr($match[0], 2490 $matchStartPos, 2491 iconv_strlen($match[0], 'UTF-8') - $matchStartPos, 2492 'UTF-8'); 2493 2494 $months = $this->_getDigitFromName($match[2]); 2495 $match[3] = self::getFullYear($match[3]); 2496 2497 if (($calc == 'set') || ($calc == 'cmp')) { 2498 --$months; 2499 --$month; 2500 --$match[1]; 2501 --$day; 2502 $match[3] -= 1970; 2503 $year -= 1970; 2504 } 2505 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true), 2506 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); 2507 break; 2508 2509 case self::RFC_822: 2510 case self::RFC_1036: 2511 // new RFC 822 format, identical to RFC 1036 standard 2512 $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); 2513 if (!$result) { 2514 require_once 'Zend/Date/Exception.php'; 2515 throw new Zend_Date_Exception("invalid date ($date) operand, RFC 822 date format expected", 0, null, $date); 2516 } 2517 2518 $months = $this->_getDigitFromName($match[2]); 2519 $match[3] = self::getFullYear($match[3]); 2520 2521 if (($calc == 'set') || ($calc == 'cmp')) { 2522 --$months; 2523 --$month; 2524 --$match[1]; 2525 --$day; 2526 $match[3] -= 1970; 2527 $year -= 1970; 2528 } 2529 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], false), 2530 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, false), false); 2531 break; 2532 2533 case self::RFC_850: 2534 $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); 2535 if (!$result) { 2536 require_once 'Zend/Date/Exception.php'; 2537 throw new Zend_Date_Exception("invalid date ($date) operand, RFC 850 date format expected", 0, null, $date); 2538 } 2539 2540 $months = $this->_getDigitFromName($match[2]); 2541 $match[3] = self::getFullYear($match[3]); 2542 2543 if (($calc == 'set') || ($calc == 'cmp')) { 2544 --$months; 2545 --$month; 2546 --$match[1]; 2547 --$day; 2548 $match[3] -= 1970; 2549 $year -= 1970; 2550 } 2551 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true), 2552 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); 2553 break; 2554 2555 case self::RFC_1123: 2556 $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); 2557 if (!$result) { 2558 require_once 'Zend/Date/Exception.php'; 2559 throw new Zend_Date_Exception("invalid date ($date) operand, RFC 1123 date format expected", 0, null, $date); 2560 } 2561 2562 $months = $this->_getDigitFromName($match[2]); 2563 2564 if (($calc == 'set') || ($calc == 'cmp')) { 2565 --$months; 2566 --$month; 2567 --$match[1]; 2568 --$day; 2569 $match[3] -= 1970; 2570 $year -= 1970; 2571 } 2572 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true), 2573 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); 2574 break; 2575 2576 case self::RSS: 2577 $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); 2578 if (!$result) { 2579 require_once 'Zend/Date/Exception.php'; 2580 throw new Zend_Date_Exception("invalid date ($date) operand, RSS date format expected", 0, null, $date); 2581 } 2582 2583 $months = $this->_getDigitFromName($match[2]); 2584 $match[3] = self::getFullYear($match[3]); 2585 2586 if (($calc == 'set') || ($calc == 'cmp')) { 2587 --$months; 2588 --$month; 2589 --$match[1]; 2590 --$day; 2591 $match[3] -= 1970; 2592 $year -= 1970; 2593 } 2594 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true), 2595 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); 2596 break; 2597 2598 case self::W3C: 2599 $result = preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})[+-]{1}\d{2}:\d{2}$/', $date, $match); 2600 if (!$result) { 2601 require_once 'Zend/Date/Exception.php'; 2602 throw new Zend_Date_Exception("invalid date ($date) operand, W3C date format expected", 0, null, $date); 2603 } 2604 2605 if (($calc == 'set') || ($calc == 'cmp')) { 2606 --$match[2]; 2607 --$month; 2608 --$match[3]; 2609 --$day; 2610 $match[1] -= 1970; 2611 $year -= 1970; 2612 } 2613 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $match[2], 1 + $match[3], 1970 + $match[1], true), 2614 $this->mktime($hour, $minute, $second, 1 + $month, 1 + $day, 1970 + $year, true), false); 2615 break; 2616 2617 default: 2618 if (!is_numeric($date) || !empty($part)) { 2619 try { 2620 if (empty($part)) { 2621 $part = Zend_Locale_Format::getDateFormat($locale) . " "; 2622 $part .= Zend_Locale_Format::getTimeFormat($locale); 2623 } 2624 2625 $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $part, 'locale' => $locale, 'fix_date' => true, 'format_type' => 'iso')); 2626 if ((strpos(strtoupper($part), 'YY') !== false) and (strpos(strtoupper($part), 'YYYY') === false)) { 2627 $parsed['year'] = self::getFullYear($parsed['year']); 2628 } 2629 2630 if (($calc == 'set') || ($calc == 'cmp')) { 2631 if (isset($parsed['month'])) { 2632 --$parsed['month']; 2633 } else { 2634 $parsed['month'] = 0; 2635 } 2636 2637 if (isset($parsed['day'])) { 2638 --$parsed['day']; 2639 } else { 2640 $parsed['day'] = 0; 2641 } 2642 2643 if (isset($parsed['year'])) { 2644 $parsed['year'] -= 1970; 2645 } else { 2646 $parsed['year'] = 0; 2647 } 2648 } 2649 2650 return $this->_assign($calc, $this->mktime( 2651 isset($parsed['hour']) ? $parsed['hour'] : 0, 2652 isset($parsed['minute']) ? $parsed['minute'] : 0, 2653 isset($parsed['second']) ? $parsed['second'] : 0, 2654 isset($parsed['month']) ? (1 + $parsed['month']) : 1, 2655 isset($parsed['day']) ? (1 + $parsed['day']) : 1, 2656 isset($parsed['year']) ? (1970 + $parsed['year']) : 1970, 2657 false), $this->getUnixTimestamp(), false); 2658 } catch (Zend_Locale_Exception $e) { 2659 if (!is_numeric($date)) { 2660 require_once 'Zend/Date/Exception.php'; 2661 throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date); 2662 } 2663 } 2664 } 2665 2666 return $this->_assign($calc, $date, $this->getUnixTimestamp(), false); 2667 break; 2668 } 2669 } 2670 2671 /** 2672 * Returns true when both date objects or date parts are equal. 2673 * For example: 2674 * 15.May.2000 <-> 15.June.2000 Equals only for Day or Year... all other will return false 2675 * 2676 * @param string|integer|array|Zend_Date $date Date or datepart to equal with 2677 * @param string $part OPTIONAL Part of the date to compare, if null the timestamp is used 2678 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2679 * @return boolean 2680 * @throws Zend_Date_Exception 2681 */ 2682 public function equals($date, $part = self::TIMESTAMP, $locale = null) 2683 { 2684 $result = $this->compare($date, $part, $locale); 2685 2686 if ($result == 0) { 2687 return true; 2688 } 2689 2690 return false; 2691 } 2692 2693 /** 2694 * Returns if the given date or datepart is earlier 2695 * For example: 2696 * 15.May.2000 <-> 13.June.1999 will return true for day, year and date, but not for month 2697 * 2698 * @param string|integer|array|Zend_Date $date Date or datepart to compare with 2699 * @param string $part OPTIONAL Part of the date to compare, if null the timestamp is used 2700 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2701 * @return boolean 2702 * @throws Zend_Date_Exception 2703 */ 2704 public function isEarlier($date, $part = null, $locale = null) 2705 { 2706 $result = $this->compare($date, $part, $locale); 2707 2708 if ($result == -1) { 2709 return true; 2710 } 2711 2712 return false; 2713 } 2714 2715 /** 2716 * Returns if the given date or datepart is later 2717 * For example: 2718 * 15.May.2000 <-> 13.June.1999 will return true for month but false for day, year and date 2719 * Returns if the given date is later 2720 * 2721 * @param string|integer|array|Zend_Date $date Date or datepart to compare with 2722 * @param string $part OPTIONAL Part of the date to compare, if null the timestamp is used 2723 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2724 * @return boolean 2725 * @throws Zend_Date_Exception 2726 */ 2727 public function isLater($date, $part = null, $locale = null) 2728 { 2729 $result = $this->compare($date, $part, $locale); 2730 2731 if ($result == 1) { 2732 return true; 2733 } 2734 2735 return false; 2736 } 2737 2738 /** 2739 * Returns only the time of the date as new Zend_Date object 2740 * For example: 2741 * 15.May.2000 10:11:23 will return a dateobject equal to 01.Jan.1970 10:11:23 2742 * 2743 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2744 * @return Zend_Date 2745 */ 2746 public function getTime($locale = null) 2747 { 2748 if (self::$_options['format_type'] == 'php') { 2749 $format = 'H:i:s'; 2750 } else { 2751 $format = self::TIME_MEDIUM; 2752 } 2753 2754 return $this->copyPart($format, $locale); 2755 } 2756 2757 /** 2758 * Returns the calculated time 2759 * 2760 * @param string $calc Calculation to make 2761 * @param string|integer|array|Zend_Date $time Time to calculate with, if null the actual time is taken 2762 * @param string $format Timeformat for parsing input 2763 * @param string|Zend_Locale $locale Locale for parsing input 2764 * @return integer|Zend_Date new time 2765 * @throws Zend_Date_Exception 2766 */ 2767 private function _time($calc, $time, $format, $locale) 2768 { 2769 if ($time === null) { 2770 require_once 'Zend/Date/Exception.php'; 2771 throw new Zend_Date_Exception('parameter $time must be set, null is not allowed'); 2772 } 2773 2774 if ($time instanceof Zend_Date) { 2775 // extract time from object 2776 $time = $time->toString('HH:mm:ss', 'iso'); 2777 } else { 2778 if (is_array($time)) { 2779 if ((isset($time['hour']) === true) or (isset($time['minute']) === true) or 2780 (isset($time['second']) === true)) { 2781 $parsed = $time; 2782 } else { 2783 require_once 'Zend/Date/Exception.php'; 2784 throw new Zend_Date_Exception("no hour, minute or second given in array"); 2785 } 2786 } else { 2787 if (self::$_options['format_type'] == 'php') { 2788 $format = Zend_Locale_Format::convertPhpToIsoFormat($format); 2789 } 2790 try { 2791 if ($locale === null) { 2792 $locale = $this->getLocale(); 2793 } 2794 2795 $parsed = Zend_Locale_Format::getTime($time, array('date_format' => $format, 'locale' => $locale, 'format_type' => 'iso')); 2796 } catch (Zend_Locale_Exception $e) { 2797 require_once 'Zend/Date/Exception.php'; 2798 throw new Zend_Date_Exception($e->getMessage(), 0, $e); 2799 } 2800 } 2801 2802 if (!array_key_exists('hour', $parsed)) { 2803 $parsed['hour'] = 0; 2804 } 2805 2806 if (!array_key_exists('minute', $parsed)) { 2807 $parsed['minute'] = 0; 2808 } 2809 2810 if (!array_key_exists('second', $parsed)) { 2811 $parsed['second'] = 0; 2812 } 2813 2814 $time = str_pad($parsed['hour'], 2, '0', STR_PAD_LEFT) . ":"; 2815 $time .= str_pad($parsed['minute'], 2, '0', STR_PAD_LEFT) . ":"; 2816 $time .= str_pad($parsed['second'], 2, '0', STR_PAD_LEFT); 2817 } 2818 2819 $return = $this->_calcdetail($calc, $time, self::TIMES, 'de'); 2820 if ($calc != 'cmp') { 2821 return $this; 2822 } 2823 2824 return $return; 2825 } 2826 2827 2828 /** 2829 * Sets a new time for the date object. Format defines how to parse the time string. 2830 * Also a complete date can be given, but only the time is used for setting. 2831 * For example: dd.MMMM.yyTHH:mm' and 'ss sec'-> 10.May.07T25:11 and 44 sec => 1h11min44sec + 1 day 2832 * Returned is the new date object and the existing date is left as it was before 2833 * 2834 * @param string|integer|array|Zend_Date $time Time to set 2835 * @param string $format OPTIONAL Timeformat for parsing input 2836 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2837 * @return Zend_Date Provides fluid interface 2838 * @throws Zend_Date_Exception 2839 */ 2840 public function setTime($time, $format = null, $locale = null) 2841 { 2842 return $this->_time('set', $time, $format, $locale); 2843 } 2844 2845 2846 /** 2847 * Adds a time to the existing date. Format defines how to parse the time string. 2848 * If only parts are given the other parts are set to 0. 2849 * If no format is given, the standardformat of this locale is used. 2850 * For example: HH:mm:ss -> 10 -> +10 hours 2851 * 2852 * @param string|integer|array|Zend_Date $time Time to add 2853 * @param string $format OPTIONAL Timeformat for parsing input 2854 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2855 * @return Zend_Date Provides fluid interface 2856 * @throws Zend_Date_Exception 2857 */ 2858 public function addTime($time, $format = null, $locale = null) 2859 { 2860 return $this->_time('add', $time, $format, $locale); 2861 } 2862 2863 2864 /** 2865 * Subtracts a time from the existing date. Format defines how to parse the time string. 2866 * If only parts are given the other parts are set to 0. 2867 * If no format is given, the standardformat of this locale is used. 2868 * For example: HH:mm:ss -> 10 -> -10 hours 2869 * 2870 * @param string|integer|array|Zend_Date $time Time to sub 2871 * @param string $format OPTIONAL Timeformat for parsing input 2872 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2873 * @return Zend_Date Provides fluid inteface 2874 * @throws Zend_Date_Exception 2875 */ 2876 public function subTime($time, $format = null, $locale = null) 2877 { 2878 return $this->_time('sub', $time, $format, $locale); 2879 } 2880 2881 2882 /** 2883 * Compares the time from the existing date. Format defines how to parse the time string. 2884 * If only parts are given the other parts are set to default. 2885 * If no format us given, the standardformat of this locale is used. 2886 * For example: HH:mm:ss -> 10 -> 10 hours 2887 * 2888 * @param string|integer|array|Zend_Date $time Time to compare 2889 * @param string $format OPTIONAL Timeformat for parsing input 2890 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2891 * @return integer 0 = equal, 1 = later, -1 = earlier 2892 * @throws Zend_Date_Exception 2893 */ 2894 public function compareTime($time, $format = null, $locale = null) 2895 { 2896 return $this->_time('cmp', $time, $format, $locale); 2897 } 2898 2899 /** 2900 * Returns a clone of $this, with the time part set to 00:00:00. 2901 * 2902 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2903 * @return Zend_Date 2904 */ 2905 public function getDate($locale = null) 2906 { 2907 $orig = self::$_options['format_type']; 2908 if (self::$_options['format_type'] == 'php') { 2909 self::$_options['format_type'] = 'iso'; 2910 } 2911 2912 $date = $this->copyPart(self::DATE_MEDIUM, $locale); 2913 $date->addTimestamp($this->getGmtOffset()); 2914 self::$_options['format_type'] = $orig; 2915 2916 return $date; 2917 } 2918 2919 /** 2920 * Returns the calculated date 2921 * 2922 * @param string $calc Calculation to make 2923 * @param string|integer|array|Zend_Date $date Date to calculate with, if null the actual date is taken 2924 * @param string $format Date format for parsing 2925 * @param string|Zend_Locale $locale Locale for parsing input 2926 * @return integer|Zend_Date new date 2927 * @throws Zend_Date_Exception 2928 */ 2929 private function _date($calc, $date, $format, $locale) 2930 { 2931 if ($date === null) { 2932 require_once 'Zend/Date/Exception.php'; 2933 throw new Zend_Date_Exception('parameter $date must be set, null is not allowed'); 2934 } 2935 2936 if ($date instanceof Zend_Date) { 2937 // extract date from object 2938 $date = $date->toString('d.M.y', 'iso'); 2939 } else { 2940 if (is_array($date)) { 2941 if ((isset($date['year']) === true) or (isset($date['month']) === true) or 2942 (isset($date['day']) === true)) { 2943 $parsed = $date; 2944 } else { 2945 require_once 'Zend/Date/Exception.php'; 2946 throw new Zend_Date_Exception("no day,month or year given in array"); 2947 } 2948 } else { 2949 if ((self::$_options['format_type'] == 'php') && !defined($format)) { 2950 $format = Zend_Locale_Format::convertPhpToIsoFormat($format); 2951 } 2952 try { 2953 if ($locale === null) { 2954 $locale = $this->getLocale(); 2955 } 2956 2957 $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'locale' => $locale, 'format_type' => 'iso')); 2958 if ((strpos(strtoupper($format), 'YY') !== false) and (strpos(strtoupper($format), 'YYYY') === false)) { 2959 $parsed['year'] = self::getFullYear($parsed['year']); 2960 } 2961 } catch (Zend_Locale_Exception $e) { 2962 require_once 'Zend/Date/Exception.php'; 2963 throw new Zend_Date_Exception($e->getMessage(), 0, $e); 2964 } 2965 } 2966 2967 if (!array_key_exists('day', $parsed)) { 2968 $parsed['day'] = 1; 2969 } 2970 2971 if (!array_key_exists('month', $parsed)) { 2972 $parsed['month'] = 1; 2973 } 2974 2975 if (!array_key_exists('year', $parsed)) { 2976 $parsed['year'] = 0; 2977 } 2978 2979 $date = $parsed['day'] . "." . $parsed['month'] . "." . $parsed['year']; 2980 } 2981 2982 $return = $this->_calcdetail($calc, $date, self::DATE_MEDIUM, 'de'); 2983 if ($calc != 'cmp') { 2984 return $this; 2985 } 2986 return $return; 2987 } 2988 2989 2990 /** 2991 * Sets a new date for the date object. Format defines how to parse the date string. 2992 * Also a complete date with time can be given, but only the date is used for setting. 2993 * For example: MMMM.yy HH:mm-> May.07 22:11 => 01.May.07 00:00 2994 * Returned is the new date object and the existing time is left as it was before 2995 * 2996 * @param string|integer|array|Zend_Date $date Date to set 2997 * @param string $format OPTIONAL Date format for parsing 2998 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 2999 * @return Zend_Date Provides fluid interface 3000 * @throws Zend_Date_Exception 3001 */ 3002 public function setDate($date, $format = null, $locale = null) 3003 { 3004 return $this->_date('set', $date, $format, $locale); 3005 } 3006 3007 3008 /** 3009 * Adds a date to the existing date object. Format defines how to parse the date string. 3010 * If only parts are given the other parts are set to 0. 3011 * If no format is given, the standardformat of this locale is used. 3012 * For example: MM.dd.YYYY -> 10 -> +10 months 3013 * 3014 * @param string|integer|array|Zend_Date $date Date to add 3015 * @param string $format OPTIONAL Date format for parsing input 3016 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3017 * @return Zend_Date Provides fluid interface 3018 * @throws Zend_Date_Exception 3019 */ 3020 public function addDate($date, $format = null, $locale = null) 3021 { 3022 return $this->_date('add', $date, $format, $locale); 3023 } 3024 3025 3026 /** 3027 * Subtracts a date from the existing date object. Format defines how to parse the date string. 3028 * If only parts are given the other parts are set to 0. 3029 * If no format is given, the standardformat of this locale is used. 3030 * For example: MM.dd.YYYY -> 10 -> -10 months 3031 * Be aware: Subtracting 2 months is not equal to Adding -2 months !!! 3032 * 3033 * @param string|integer|array|Zend_Date $date Date to sub 3034 * @param string $format OPTIONAL Date format for parsing input 3035 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3036 * @return Zend_Date Provides fluid interface 3037 * @throws Zend_Date_Exception 3038 */ 3039 public function subDate($date, $format = null, $locale = null) 3040 { 3041 return $this->_date('sub', $date, $format, $locale); 3042 } 3043 3044 3045 /** 3046 * Compares the date from the existing date object, ignoring the time. 3047 * Format defines how to parse the date string. 3048 * If only parts are given the other parts are set to 0. 3049 * If no format is given, the standardformat of this locale is used. 3050 * For example: 10.01.2000 => 10.02.1999 -> false 3051 * 3052 * @param string|integer|array|Zend_Date $date Date to compare 3053 * @param string $format OPTIONAL Date format for parsing input 3054 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3055 * @return integer 0 = equal, 1 = later, -1 = earlier 3056 * @throws Zend_Date_Exception 3057 */ 3058 public function compareDate($date, $format = null, $locale = null) 3059 { 3060 return $this->_date('cmp', $date, $format, $locale); 3061 } 3062 3063 3064 /** 3065 * Returns the full ISO 8601 date from the date object. 3066 * Always the complete ISO 8601 specifiction is used. If an other ISO date is needed 3067 * (ISO 8601 defines several formats) use toString() instead. 3068 * This function does not return the ISO date as object. Use copy() instead. 3069 * 3070 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3071 * @return string 3072 */ 3073 public function getIso($locale = null) 3074 { 3075 return $this->toString(self::ISO_8601, 'iso', $locale); 3076 } 3077 3078 3079 /** 3080 * Sets a new date for the date object. Not given parts are set to default. 3081 * Only supported ISO 8601 formats are accepted. 3082 * For example: 050901 -> 01.Sept.2005 00:00:00, 20050201T10:00:30 -> 01.Feb.2005 10h00m30s 3083 * Returned is the new date object 3084 * 3085 * @param string|integer|Zend_Date $date ISO Date to set 3086 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3087 * @return Zend_Date Provides fluid interface 3088 * @throws Zend_Date_Exception 3089 */ 3090 public function setIso($date, $locale = null) 3091 { 3092 return $this->_calcvalue('set', $date, 'iso', self::ISO_8601, $locale); 3093 } 3094 3095 3096 /** 3097 * Adds a ISO date to the date object. Not given parts are set to default. 3098 * Only supported ISO 8601 formats are accepted. 3099 * For example: 050901 -> + 01.Sept.2005 00:00:00, 10:00:00 -> +10h 3100 * Returned is the new date object 3101 * 3102 * @param string|integer|Zend_Date $date ISO Date to add 3103 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3104 * @return Zend_Date Provides fluid interface 3105 * @throws Zend_Date_Exception 3106 */ 3107 public function addIso($date, $locale = null) 3108 { 3109 return $this->_calcvalue('add', $date, 'iso', self::ISO_8601, $locale); 3110 } 3111 3112 3113 /** 3114 * Subtracts a ISO date from the date object. Not given parts are set to default. 3115 * Only supported ISO 8601 formats are accepted. 3116 * For example: 050901 -> - 01.Sept.2005 00:00:00, 10:00:00 -> -10h 3117 * Returned is the new date object 3118 * 3119 * @param string|integer|Zend_Date $date ISO Date to sub 3120 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3121 * @return Zend_Date Provides fluid interface 3122 * @throws Zend_Date_Exception 3123 */ 3124 public function subIso($date, $locale = null) 3125 { 3126 return $this->_calcvalue('sub', $date, 'iso', self::ISO_8601, $locale); 3127 } 3128 3129 3130 /** 3131 * Compares a ISO date with the date object. Not given parts are set to default. 3132 * Only supported ISO 8601 formats are accepted. 3133 * For example: 050901 -> - 01.Sept.2005 00:00:00, 10:00:00 -> -10h 3134 * Returns if equal, earlier or later 3135 * 3136 * @param string|integer|Zend_Date $date ISO Date to sub 3137 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3138 * @return integer 0 = equal, 1 = later, -1 = earlier 3139 * @throws Zend_Date_Exception 3140 */ 3141 public function compareIso($date, $locale = null) 3142 { 3143 return $this->_calcvalue('cmp', $date, 'iso', self::ISO_8601, $locale); 3144 } 3145 3146 3147 /** 3148 * Returns a RFC 822 compilant datestring from the date object. 3149 * This function does not return the RFC date as object. Use copy() instead. 3150 * 3151 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3152 * @return string 3153 */ 3154 public function getArpa($locale = null) 3155 { 3156 if (self::$_options['format_type'] == 'php') { 3157 $format = 'D\, d M y H\:i\:s O'; 3158 } else { 3159 $format = self::RFC_822; 3160 } 3161 3162 return $this->toString($format, 'iso', $locale); 3163 } 3164 3165 3166 /** 3167 * Sets a RFC 822 date as new date for the date object. 3168 * Only RFC 822 compilant date strings are accepted. 3169 * For example: Sat, 14 Feb 09 00:31:30 +0100 3170 * Returned is the new date object 3171 * 3172 * @param string|integer|Zend_Date $date RFC 822 to set 3173 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3174 * @return Zend_Date Provides fluid interface 3175 * @throws Zend_Date_Exception 3176 */ 3177 public function setArpa($date, $locale = null) 3178 { 3179 return $this->_calcvalue('set', $date, 'arpa', self::RFC_822, $locale); 3180 } 3181 3182 3183 /** 3184 * Adds a RFC 822 date to the date object. 3185 * ARPA messages are used in emails or HTTP Headers. 3186 * Only RFC 822 compilant date strings are accepted. 3187 * For example: Sat, 14 Feb 09 00:31:30 +0100 3188 * Returned is the new date object 3189 * 3190 * @param string|integer|Zend_Date $date RFC 822 Date to add 3191 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3192 * @return Zend_Date Provides fluid interface 3193 * @throws Zend_Date_Exception 3194 */ 3195 public function addArpa($date, $locale = null) 3196 { 3197 return $this->_calcvalue('add', $date, 'arpa', self::RFC_822, $locale); 3198 } 3199 3200 3201 /** 3202 * Subtracts a RFC 822 date from the date object. 3203 * ARPA messages are used in emails or HTTP Headers. 3204 * Only RFC 822 compilant date strings are accepted. 3205 * For example: Sat, 14 Feb 09 00:31:30 +0100 3206 * Returned is the new date object 3207 * 3208 * @param string|integer|Zend_Date $date RFC 822 Date to sub 3209 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3210 * @return Zend_Date Provides fluid interface 3211 * @throws Zend_Date_Exception 3212 */ 3213 public function subArpa($date, $locale = null) 3214 { 3215 return $this->_calcvalue('sub', $date, 'arpa', self::RFC_822, $locale); 3216 } 3217 3218 3219 /** 3220 * Compares a RFC 822 compilant date with the date object. 3221 * ARPA messages are used in emails or HTTP Headers. 3222 * Only RFC 822 compilant date strings are accepted. 3223 * For example: Sat, 14 Feb 09 00:31:30 +0100 3224 * Returns if equal, earlier or later 3225 * 3226 * @param string|integer|Zend_Date $date RFC 822 Date to sub 3227 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3228 * @return integer 0 = equal, 1 = later, -1 = earlier 3229 * @throws Zend_Date_Exception 3230 */ 3231 public function compareArpa($date, $locale = null) 3232 { 3233 return $this->_calcvalue('cmp', $date, 'arpa', self::RFC_822, $locale); 3234 } 3235 3236 3237 /** 3238 * Check if location is supported 3239 * 3240 * @param $location array - locations array 3241 * @return $horizon float 3242 */ 3243 private function _checkLocation($location) 3244 { 3245 if (!isset($location['longitude']) or !isset($location['latitude'])) { 3246 require_once 'Zend/Date/Exception.php'; 3247 throw new Zend_Date_Exception('Location must include \'longitude\' and \'latitude\'', 0, null, $location); 3248 } 3249 if (($location['longitude'] > 180) or ($location['longitude'] < -180)) { 3250 require_once 'Zend/Date/Exception.php'; 3251 throw new Zend_Date_Exception('Longitude must be between -180 and 180', 0, null, $location); 3252 } 3253 if (($location['latitude'] > 90) or ($location['latitude'] < -90)) { 3254 require_once 'Zend/Date/Exception.php'; 3255 throw new Zend_Date_Exception('Latitude must be between -90 and 90', 0, null, $location); 3256 } 3257 3258 if (!isset($location['horizon'])){ 3259 $location['horizon'] = 'effective'; 3260 } 3261 3262 switch ($location['horizon']) { 3263 case 'civil' : 3264 return -0.104528; 3265 break; 3266 case 'nautic' : 3267 return -0.207912; 3268 break; 3269 case 'astronomic' : 3270 return -0.309017; 3271 break; 3272 default : 3273 return -0.0145439; 3274 break; 3275 } 3276 } 3277 3278 3279 /** 3280 * Returns the time of sunrise for this date and a given location as new date object 3281 * For a list of cities and correct locations use the class Zend_Date_Cities 3282 * 3283 * @param $location array - location of sunrise 3284 * ['horizon'] -> civil, nautic, astronomical, effective (default) 3285 * ['longitude'] -> longitude of location 3286 * ['latitude'] -> latitude of location 3287 * @return Zend_Date 3288 * @throws Zend_Date_Exception 3289 */ 3290 public function getSunrise($location) 3291 { 3292 $horizon = $this->_checkLocation($location); 3293 $result = clone $this; 3294 $result->set($this->calcSun($location, $horizon, true), self::TIMESTAMP); 3295 return $result; 3296 } 3297 3298 3299 /** 3300 * Returns the time of sunset for this date and a given location as new date object 3301 * For a list of cities and correct locations use the class Zend_Date_Cities 3302 * 3303 * @param $location array - location of sunset 3304 * ['horizon'] -> civil, nautic, astronomical, effective (default) 3305 * ['longitude'] -> longitude of location 3306 * ['latitude'] -> latitude of location 3307 * @return Zend_Date 3308 * @throws Zend_Date_Exception 3309 */ 3310 public function getSunset($location) 3311 { 3312 $horizon = $this->_checkLocation($location); 3313 $result = clone $this; 3314 $result->set($this->calcSun($location, $horizon, false), self::TIMESTAMP); 3315 return $result; 3316 } 3317 3318 3319 /** 3320 * Returns an array with the sunset and sunrise dates for all horizon types 3321 * For a list of cities and correct locations use the class Zend_Date_Cities 3322 * 3323 * @param $location array - location of suninfo 3324 * ['horizon'] -> civil, nautic, astronomical, effective (default) 3325 * ['longitude'] -> longitude of location 3326 * ['latitude'] -> latitude of location 3327 * @return array - [sunset|sunrise][effective|civil|nautic|astronomic] 3328 * @throws Zend_Date_Exception 3329 */ 3330 public function getSunInfo($location) 3331 { 3332 $suninfo = array(); 3333 for ($i = 0; $i < 4; ++$i) { 3334 switch ($i) { 3335 case 0 : 3336 $location['horizon'] = 'effective'; 3337 break; 3338 case 1 : 3339 $location['horizon'] = 'civil'; 3340 break; 3341 case 2 : 3342 $location['horizon'] = 'nautic'; 3343 break; 3344 case 3 : 3345 $location['horizon'] = 'astronomic'; 3346 break; 3347 } 3348 $horizon = $this->_checkLocation($location); 3349 $result = clone $this; 3350 $result->set($this->calcSun($location, $horizon, true), self::TIMESTAMP); 3351 $suninfo['sunrise'][$location['horizon']] = $result; 3352 $result = clone $this; 3353 $result->set($this->calcSun($location, $horizon, false), self::TIMESTAMP); 3354 $suninfo['sunset'][$location['horizon']] = $result; 3355 } 3356 return $suninfo; 3357 } 3358 3359 3360 /** 3361 * Check a given year for leap year. 3362 * 3363 * @param integer|array|Zend_Date $year Year to check 3364 * @return boolean 3365 */ 3366 public static function checkLeapYear($year) 3367 { 3368 if ($year instanceof Zend_Date) { 3369 $year = (int) $year->toString(self::YEAR, 'iso'); 3370 } 3371 3372 if (is_array($year)) { 3373 if (isset($year['year']) === true) { 3374 $year = $year['year']; 3375 } else { 3376 require_once 'Zend/Date/Exception.php'; 3377 throw new Zend_Date_Exception("no year given in array"); 3378 } 3379 } 3380 3381 if (!is_numeric($year)) { 3382 require_once 'Zend/Date/Exception.php'; 3383 throw new Zend_Date_Exception("year ($year) has to be integer for checkLeapYear()", 0, null, $year); 3384 } 3385 3386 return (bool) parent::isYearLeapYear($year); 3387 } 3388 3389 3390 /** 3391 * Returns true, if the year is a leap year. 3392 * 3393 * @return boolean 3394 */ 3395 public function isLeapYear() 3396 { 3397 return self::checkLeapYear($this); 3398 } 3399 3400 3401 /** 3402 * Returns if the set date is todays date 3403 * 3404 * @return boolean 3405 */ 3406 public function isToday() 3407 { 3408 $today = $this->date('Ymd', $this->_getTime()); 3409 $day = $this->date('Ymd', $this->getUnixTimestamp()); 3410 return ($today == $day); 3411 } 3412 3413 3414 /** 3415 * Returns if the set date is yesterdays date 3416 * 3417 * @return boolean 3418 */ 3419 public function isYesterday() 3420 { 3421 list($year, $month, $day) = explode('-', $this->date('Y-m-d', $this->_getTime())); 3422 // adjusts for leap days and DST changes that are timezone specific 3423 $yesterday = $this->date('Ymd', $this->mktime(0, 0, 0, $month, $day -1, $year)); 3424 $day = $this->date('Ymd', $this->getUnixTimestamp()); 3425 return $day == $yesterday; 3426 } 3427 3428 3429 /** 3430 * Returns if the set date is tomorrows date 3431 * 3432 * @return boolean 3433 */ 3434 public function isTomorrow() 3435 { 3436 list($year, $month, $day) = explode('-', $this->date('Y-m-d', $this->_getTime())); 3437 // adjusts for leap days and DST changes that are timezone specific 3438 $tomorrow = $this->date('Ymd', $this->mktime(0, 0, 0, $month, $day +1, $year)); 3439 $day = $this->date('Ymd', $this->getUnixTimestamp()); 3440 return $day == $tomorrow; 3441 } 3442 3443 /** 3444 * Returns the actual date as new date object 3445 * 3446 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3447 * @return Zend_Date 3448 */ 3449 public static function now($locale = null) 3450 { 3451 return new Zend_Date(time(), self::TIMESTAMP, $locale); 3452 } 3453 3454 /** 3455 * Calculate date details 3456 * 3457 * @param string $calc Calculation to make 3458 * @param string|integer|array|Zend_Date $date Date or Part to calculate 3459 * @param string $part Datepart for Calculation 3460 * @param string|Zend_Locale $locale Locale for parsing input 3461 * @return integer|string new date 3462 * @throws Zend_Date_Exception 3463 */ 3464 private function _calcdetail($calc, $date, $type, $locale) 3465 { 3466 $old = false; 3467 if (self::$_options['format_type'] == 'php') { 3468 self::$_options['format_type'] = 'iso'; 3469 $old = true; 3470 } 3471 3472 switch($calc) { 3473 case 'set' : 3474 $return = $this->set($date, $type, $locale); 3475 break; 3476 case 'add' : 3477 $return = $this->add($date, $type, $locale); 3478 break; 3479 case 'sub' : 3480 $return = $this->sub($date, $type, $locale); 3481 break; 3482 default : 3483 $return = $this->compare($date, $type, $locale); 3484 break; 3485 } 3486 3487 if ($old) { 3488 self::$_options['format_type'] = 'php'; 3489 } 3490 3491 return $return; 3492 } 3493 3494 /** 3495 * Internal calculation, returns the requested date type 3496 * 3497 * @param string $calc Calculation to make 3498 * @param string|integer|Zend_Date $value Datevalue to calculate with, if null the actual value is taken 3499 * @param string|Zend_Locale $locale Locale for parsing input 3500 * @return integer|Zend_Date new date 3501 * @throws Zend_Date_Exception 3502 */ 3503 private function _calcvalue($calc, $value, $type, $parameter, $locale) 3504 { 3505 if ($value === null) { 3506 require_once 'Zend/Date/Exception.php'; 3507 throw new Zend_Date_Exception("parameter $type must be set, null is not allowed"); 3508 } 3509 3510 if ($locale === null) { 3511 $locale = $this->getLocale(); 3512 } 3513 3514 if ($value instanceof Zend_Date) { 3515 // extract value from object 3516 $value = $value->toString($parameter, 'iso', $locale); 3517 } else if (!is_array($value) && !is_numeric($value) && ($type != 'iso') && ($type != 'arpa')) { 3518 require_once 'Zend/Date/Exception.php'; 3519 throw new Zend_Date_Exception("invalid $type ($value) operand", 0, null, $value); 3520 } 3521 3522 $return = $this->_calcdetail($calc, $value, $parameter, $locale); 3523 if ($calc != 'cmp') { 3524 return $this; 3525 } 3526 return $return; 3527 } 3528 3529 3530 /** 3531 * Returns only the year from the date object as new object. 3532 * For example: 10.May.2000 10:30:00 -> 01.Jan.2000 00:00:00 3533 * 3534 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3535 * @return Zend_Date 3536 */ 3537 public function getYear($locale = null) 3538 { 3539 if (self::$_options['format_type'] == 'php') { 3540 $format = 'Y'; 3541 } else { 3542 $format = self::YEAR; 3543 } 3544 3545 return $this->copyPart($format, $locale); 3546 } 3547 3548 3549 /** 3550 * Sets a new year 3551 * If the year is between 0 and 69, 2000 will be set (2000-2069) 3552 * If the year if between 70 and 99, 1999 will be set (1970-1999) 3553 * 3 or 4 digit years are set as expected. If you need to set year 0-99 3554 * use set() instead. 3555 * Returned is the new date object 3556 * 3557 * @param string|integer|array|Zend_Date $date Year to set 3558 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3559 * @return Zend_Date Provides fluid interface 3560 * @throws Zend_Date_Exception 3561 */ 3562 public function setYear($year, $locale = null) 3563 { 3564 return $this->_calcvalue('set', $year, 'year', self::YEAR, $locale); 3565 } 3566 3567 3568 /** 3569 * Adds the year to the existing date object 3570 * If the year is between 0 and 69, 2000 will be added (2000-2069) 3571 * If the year if between 70 and 99, 1999 will be added (1970-1999) 3572 * 3 or 4 digit years are added as expected. If you need to add years from 0-99 3573 * use add() instead. 3574 * Returned is the new date object 3575 * 3576 * @param string|integer|array|Zend_Date $date Year to add 3577 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3578 * @return Zend_Date Provides fluid interface 3579 * @throws Zend_Date_Exception 3580 */ 3581 public function addYear($year, $locale = null) 3582 { 3583 return $this->_calcvalue('add', $year, 'year', self::YEAR, $locale); 3584 } 3585 3586 3587 /** 3588 * Subs the year from the existing date object 3589 * If the year is between 0 and 69, 2000 will be subtracted (2000-2069) 3590 * If the year if between 70 and 99, 1999 will be subtracted (1970-1999) 3591 * 3 or 4 digit years are subtracted as expected. If you need to subtract years from 0-99 3592 * use sub() instead. 3593 * Returned is the new date object 3594 * 3595 * @param string|integer|array|Zend_Date $date Year to sub 3596 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3597 * @return Zend_Date Provides fluid interface 3598 * @throws Zend_Date_Exception 3599 */ 3600 public function subYear($year, $locale = null) 3601 { 3602 return $this->_calcvalue('sub', $year, 'year', self::YEAR, $locale); 3603 } 3604 3605 3606 /** 3607 * Compares the year with the existing date object, ignoring other date parts. 3608 * For example: 10.03.2000 -> 15.02.2000 -> true 3609 * Returns if equal, earlier or later 3610 * 3611 * @param string|integer|array|Zend_Date $year Year to compare 3612 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3613 * @return integer 0 = equal, 1 = later, -1 = earlier 3614 * @throws Zend_Date_Exception 3615 */ 3616 public function compareYear($year, $locale = null) 3617 { 3618 return $this->_calcvalue('cmp', $year, 'year', self::YEAR, $locale); 3619 } 3620 3621 3622 /** 3623 * Returns only the month from the date object as new object. 3624 * For example: 10.May.2000 10:30:00 -> 01.May.1970 00:00:00 3625 * 3626 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3627 * @return Zend_Date 3628 */ 3629 public function getMonth($locale = null) 3630 { 3631 if (self::$_options['format_type'] == 'php') { 3632 $format = 'm'; 3633 } else { 3634 $format = self::MONTH; 3635 } 3636 3637 return $this->copyPart($format, $locale); 3638 } 3639 3640 3641 /** 3642 * Returns the calculated month 3643 * 3644 * @param string $calc Calculation to make 3645 * @param string|integer|array|Zend_Date $month Month to calculate with, if null the actual month is taken 3646 * @param string|Zend_Locale $locale Locale for parsing input 3647 * @return integer|Zend_Date new time 3648 * @throws Zend_Date_Exception 3649 */ 3650 private function _month($calc, $month, $locale) 3651 { 3652 if ($month === null) { 3653 require_once 'Zend/Date/Exception.php'; 3654 throw new Zend_Date_Exception('parameter $month must be set, null is not allowed'); 3655 } 3656 3657 if ($locale === null) { 3658 $locale = $this->getLocale(); 3659 } 3660 3661 if ($month instanceof Zend_Date) { 3662 // extract month from object 3663 $found = $month->toString(self::MONTH_SHORT, 'iso', $locale); 3664 } else { 3665 if (is_numeric($month)) { 3666 $found = $month; 3667 } else if (is_array($month)) { 3668 if (isset($month['month']) === true) { 3669 $month = $month['month']; 3670 } else { 3671 require_once 'Zend/Date/Exception.php'; 3672 throw new Zend_Date_Exception("no month given in array"); 3673 } 3674 } else { 3675 $monthlist = Zend_Locale_Data::getList($locale, 'month'); 3676 $monthlist2 = Zend_Locale_Data::getList($locale, 'month', array('gregorian', 'format', 'abbreviated')); 3677 3678 $monthlist = array_merge($monthlist, $monthlist2); 3679 $found = 0; 3680 $cnt = 0; 3681 foreach ($monthlist as $key => $value) { 3682 if (strtoupper($value) == strtoupper($month)) { 3683 $found = ($key % 12) + 1; 3684 break; 3685 } 3686 ++$cnt; 3687 } 3688 if ($found == 0) { 3689 foreach ($monthlist2 as $key => $value) { 3690 if (strtoupper(iconv_substr($value, 0, 1, 'UTF-8')) == strtoupper($month)) { 3691 $found = $key + 1; 3692 break; 3693 } 3694 ++$cnt; 3695 } 3696 } 3697 if ($found == 0) { 3698 require_once 'Zend/Date/Exception.php'; 3699 throw new Zend_Date_Exception("unknown month name ($month)", 0, null, $month); 3700 } 3701 } 3702 } 3703 $return = $this->_calcdetail($calc, $found, self::MONTH_SHORT, $locale); 3704 if ($calc != 'cmp') { 3705 return $this; 3706 } 3707 return $return; 3708 } 3709 3710 3711 /** 3712 * Sets a new month 3713 * The month can be a number or a string. Setting months lower then 0 and greater then 12 3714 * will result in adding or subtracting the relevant year. (12 months equal one year) 3715 * If a localized monthname is given it will be parsed with the default locale or the optional 3716 * set locale. 3717 * Returned is the new date object 3718 * 3719 * @param string|integer|array|Zend_Date $month Month to set 3720 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3721 * @return Zend_Date Provides fluid interface 3722 * @throws Zend_Date_Exception 3723 */ 3724 public function setMonth($month, $locale = null) 3725 { 3726 return $this->_month('set', $month, $locale); 3727 } 3728 3729 3730 /** 3731 * Adds months to the existing date object. 3732 * The month can be a number or a string. Adding months lower then 0 and greater then 12 3733 * will result in adding or subtracting the relevant year. (12 months equal one year) 3734 * If a localized monthname is given it will be parsed with the default locale or the optional 3735 * set locale. 3736 * Returned is the new date object 3737 * 3738 * @param string|integer|array|Zend_Date $month Month to add 3739 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3740 * @return Zend_Date Provides fluid interface 3741 * @throws Zend_Date_Exception 3742 */ 3743 public function addMonth($month, $locale = null) 3744 { 3745 return $this->_month('add', $month, $locale); 3746 } 3747 3748 3749 /** 3750 * Subtracts months from the existing date object. 3751 * The month can be a number or a string. Subtracting months lower then 0 and greater then 12 3752 * will result in adding or subtracting the relevant year. (12 months equal one year) 3753 * If a localized monthname is given it will be parsed with the default locale or the optional 3754 * set locale. 3755 * Returned is the new date object 3756 * 3757 * @param string|integer|array|Zend_Date $month Month to sub 3758 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3759 * @return Zend_Date Provides fluid interface 3760 * @throws Zend_Date_Exception 3761 */ 3762 public function subMonth($month, $locale = null) 3763 { 3764 return $this->_month('sub', $month, $locale); 3765 } 3766 3767 3768 /** 3769 * Compares the month with the existing date object, ignoring other date parts. 3770 * For example: 10.03.2000 -> 15.03.1950 -> true 3771 * Returns if equal, earlier or later 3772 * 3773 * @param string|integer|array|Zend_Date $month Month to compare 3774 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3775 * @return integer 0 = equal, 1 = later, -1 = earlier 3776 * @throws Zend_Date_Exception 3777 */ 3778 public function compareMonth($month, $locale = null) 3779 { 3780 return $this->_month('cmp', $month, $locale); 3781 } 3782 3783 3784 /** 3785 * Returns the day as new date object 3786 * Example: 20.May.1986 -> 20.Jan.1970 00:00:00 3787 * 3788 * @param $locale string|Zend_Locale OPTIONAL Locale for parsing input 3789 * @return Zend_Date 3790 */ 3791 public function getDay($locale = null) 3792 { 3793 return $this->copyPart(self::DAY_SHORT, $locale); 3794 } 3795 3796 3797 /** 3798 * Returns the calculated day 3799 * 3800 * @param $calc string Type of calculation to make 3801 * @param $day string|integer|Zend_Date Day to calculate, when null the actual day is calculated 3802 * @param $locale string|Zend_Locale Locale for parsing input 3803 * @return Zend_Date|integer 3804 */ 3805 private function _day($calc, $day, $locale) 3806 { 3807 if ($day === null) { 3808 require_once 'Zend/Date/Exception.php'; 3809 throw new Zend_Date_Exception('parameter $day must be set, null is not allowed'); 3810 } 3811 3812 if ($locale === null) { 3813 $locale = $this->getLocale(); 3814 } 3815 3816 if ($day instanceof Zend_Date) { 3817 $day = $day->toString(self::DAY_SHORT, 'iso', $locale); 3818 } 3819 3820 if (is_numeric($day)) { 3821 $type = self::DAY_SHORT; 3822 } else if (is_array($day)) { 3823 if (isset($day['day']) === true) { 3824 $day = $day['day']; 3825 $type = self::WEEKDAY; 3826 } else { 3827 require_once 'Zend/Date/Exception.php'; 3828 throw new Zend_Date_Exception("no day given in array"); 3829 } 3830 } else { 3831 switch (iconv_strlen($day, 'UTF-8')) { 3832 case 1 : 3833 $type = self::WEEKDAY_NARROW; 3834 break; 3835 case 2: 3836 $type = self::WEEKDAY_NAME; 3837 break; 3838 case 3: 3839 $type = self::WEEKDAY_SHORT; 3840 break; 3841 default: 3842 $type = self::WEEKDAY; 3843 break; 3844 } 3845 } 3846 $return = $this->_calcdetail($calc, $day, $type, $locale); 3847 if ($calc != 'cmp') { 3848 return $this; 3849 } 3850 return $return; 3851 } 3852 3853 3854 /** 3855 * Sets a new day 3856 * The day can be a number or a string. Setting days lower then 0 or greater than the number of this months days 3857 * will result in adding or subtracting the relevant month. 3858 * If a localized dayname is given it will be parsed with the default locale or the optional 3859 * set locale. 3860 * Returned is the new date object 3861 * Example: setDay('Montag', 'de_AT'); will set the monday of this week as day. 3862 * 3863 * @param string|integer|array|Zend_Date $month Day to set 3864 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3865 * @return Zend_Date Provides fluid interface 3866 * @throws Zend_Date_Exception 3867 */ 3868 public function setDay($day, $locale = null) 3869 { 3870 return $this->_day('set', $day, $locale); 3871 } 3872 3873 3874 /** 3875 * Adds days to the existing date object. 3876 * The day can be a number or a string. Adding days lower then 0 or greater than the number of this months days 3877 * will result in adding or subtracting the relevant month. 3878 * If a localized dayname is given it will be parsed with the default locale or the optional 3879 * set locale. 3880 * 3881 * @param string|integer|array|Zend_Date $month Day to add 3882 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3883 * @return Zend_Date Provides fluid interface 3884 * @throws Zend_Date_Exception 3885 */ 3886 public function addDay($day, $locale = null) 3887 { 3888 return $this->_day('add', $day, $locale); 3889 } 3890 3891 3892 /** 3893 * Subtracts days from the existing date object. 3894 * The day can be a number or a string. Subtracting days lower then 0 or greater than the number of this months days 3895 * will result in adding or subtracting the relevant month. 3896 * If a localized dayname is given it will be parsed with the default locale or the optional 3897 * set locale. 3898 * 3899 * @param string|integer|array|Zend_Date $month Day to sub 3900 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3901 * @return Zend_Date Provides fluid interface 3902 * @throws Zend_Date_Exception 3903 */ 3904 public function subDay($day, $locale = null) 3905 { 3906 return $this->_day('sub', $day, $locale); 3907 } 3908 3909 3910 /** 3911 * Compares the day with the existing date object, ignoring other date parts. 3912 * For example: 'Monday', 'en' -> 08.Jan.2007 -> 0 3913 * Returns if equal, earlier or later 3914 * 3915 * @param string|integer|array|Zend_Date $day Day to compare 3916 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 3917 * @return integer 0 = equal, 1 = later, -1 = earlier 3918 * @throws Zend_Date_Exception 3919 */ 3920 public function compareDay($day, $locale = null) 3921 { 3922 return $this->_day('cmp', $day, $locale); 3923 } 3924 3925 3926 /** 3927 * Returns the weekday as new date object 3928 * Weekday is always from 1-7 3929 * Example: 09-Jan-2007 -> 2 = Tuesday -> 02-Jan-1970 (when 02.01.1970 is also Tuesday) 3930 * 3931 * @param $locale string|Zend_Locale OPTIONAL Locale for parsing input 3932 * @return Zend_Date 3933 */ 3934 public function getWeekday($locale = null) 3935 { 3936 if (self::$_options['format_type'] == 'php') { 3937 $format = 'l'; 3938 } else { 3939 $format = self::WEEKDAY; 3940 } 3941 3942 return $this->copyPart($format, $locale); 3943 } 3944 3945 3946 /** 3947 * Returns the calculated weekday 3948 * 3949 * @param $calc string Type of calculation to make 3950 * @param $weekday string|integer|array|Zend_Date Weekday to calculate, when null the actual weekday is calculated 3951 * @param $locale string|Zend_Locale Locale for parsing input 3952 * @return Zend_Date|integer 3953 * @throws Zend_Date_Exception 3954 */ 3955 private function _weekday($calc, $weekday, $locale) 3956 { 3957 if ($weekday === null) { 3958 require_once 'Zend/Date/Exception.php'; 3959 throw new Zend_Date_Exception('parameter $weekday must be set, null is not allowed'); 3960 } 3961 3962 if ($locale === null) { 3963 $locale = $this->getLocale(); 3964 } 3965 3966 if ($weekday instanceof Zend_Date) { 3967 $weekday = $weekday->toString(self::WEEKDAY_8601, 'iso', $locale); 3968 } 3969 3970 if (is_numeric($weekday)) { 3971 $type = self::WEEKDAY_8601; 3972 } else if (is_array($weekday)) { 3973 if (isset($weekday['weekday']) === true) { 3974 $weekday = $weekday['weekday']; 3975 $type = self::WEEKDAY; 3976 } else { 3977 require_once 'Zend/Date/Exception.php'; 3978 throw new Zend_Date_Exception("no weekday given in array"); 3979 } 3980 } else { 3981 switch(iconv_strlen($weekday, 'UTF-8')) { 3982 case 1: 3983 $type = self::WEEKDAY_NARROW; 3984 break; 3985 case 2: 3986 $type = self::WEEKDAY_NAME; 3987 break; 3988 case 3: 3989 $type = self::WEEKDAY_SHORT; 3990 break; 3991 default: 3992 $type = self::WEEKDAY; 3993 break; 3994 } 3995 } 3996 $return = $this->_calcdetail($calc, $weekday, $type, $locale); 3997 if ($calc != 'cmp') { 3998 return $this; 3999 } 4000 return $return; 4001 } 4002 4003 4004 /** 4005 * Sets a new weekday 4006 * The weekday can be a number or a string. If a localized weekday name is given, 4007 * then it will be parsed as a date in $locale (defaults to the same locale as $this). 4008 * Returned is the new date object. 4009 * Example: setWeekday(3); will set the wednesday of this week as day. 4010 * 4011 * @param string|integer|array|Zend_Date $month Weekday to set 4012 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4013 * @return Zend_Date Provides fluid interface 4014 * @throws Zend_Date_Exception 4015 */ 4016 public function setWeekday($weekday, $locale = null) 4017 { 4018 return $this->_weekday('set', $weekday, $locale); 4019 } 4020 4021 4022 /** 4023 * Adds weekdays to the existing date object. 4024 * The weekday can be a number or a string. 4025 * If a localized dayname is given it will be parsed with the default locale or the optional 4026 * set locale. 4027 * Returned is the new date object 4028 * Example: addWeekday(3); will add the difference of days from the begining of the month until 4029 * wednesday. 4030 * 4031 * @param string|integer|array|Zend_Date $month Weekday to add 4032 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4033 * @return Zend_Date Provides fluid interface 4034 * @throws Zend_Date_Exception 4035 */ 4036 public function addWeekday($weekday, $locale = null) 4037 { 4038 return $this->_weekday('add', $weekday, $locale); 4039 } 4040 4041 4042 /** 4043 * Subtracts weekdays from the existing date object. 4044 * The weekday can be a number or a string. 4045 * If a localized dayname is given it will be parsed with the default locale or the optional 4046 * set locale. 4047 * Returned is the new date object 4048 * Example: subWeekday(3); will subtract the difference of days from the begining of the month until 4049 * wednesday. 4050 * 4051 * @param string|integer|array|Zend_Date $month Weekday to sub 4052 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4053 * @return Zend_Date Provides fluid interface 4054 * @throws Zend_Date_Exception 4055 */ 4056 public function subWeekday($weekday, $locale = null) 4057 { 4058 return $this->_weekday('sub', $weekday, $locale); 4059 } 4060 4061 4062 /** 4063 * Compares the weekday with the existing date object, ignoring other date parts. 4064 * For example: 'Monday', 'en' -> 08.Jan.2007 -> 0 4065 * Returns if equal, earlier or later 4066 * 4067 * @param string|integer|array|Zend_Date $weekday Weekday to compare 4068 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4069 * @return integer 0 = equal, 1 = later, -1 = earlier 4070 * @throws Zend_Date_Exception 4071 */ 4072 public function compareWeekday($weekday, $locale = null) 4073 { 4074 return $this->_weekday('cmp', $weekday, $locale); 4075 } 4076 4077 4078 /** 4079 * Returns the day of year as new date object 4080 * Example: 02.Feb.1986 10:00:00 -> 02.Feb.1970 00:00:00 4081 * 4082 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4083 * @return Zend_Date 4084 */ 4085 public function getDayOfYear($locale = null) 4086 { 4087 if (self::$_options['format_type'] == 'php') { 4088 $format = 'D'; 4089 } else { 4090 $format = self::DAY_OF_YEAR; 4091 } 4092 4093 return $this->copyPart($format, $locale); 4094 } 4095 4096 4097 /** 4098 * Sets a new day of year 4099 * The day of year is always a number. 4100 * Returned is the new date object 4101 * Example: 04.May.2004 -> setDayOfYear(10) -> 10.Jan.2004 4102 * 4103 * @param string|integer|array|Zend_Date $day Day of Year to set 4104 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4105 * @return Zend_Date Provides fluid interface 4106 * @throws Zend_Date_Exception 4107 */ 4108 public function setDayOfYear($day, $locale = null) 4109 { 4110 return $this->_calcvalue('set', $day, 'day of year', self::DAY_OF_YEAR, $locale); 4111 } 4112 4113 4114 /** 4115 * Adds a day of year to the existing date object. 4116 * The day of year is always a number. 4117 * Returned is the new date object 4118 * Example: addDayOfYear(10); will add 10 days to the existing date object. 4119 * 4120 * @param string|integer|array|Zend_Date $day Day of Year to add 4121 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4122 * @return Zend_Date Provides fluid interface 4123 * @throws Zend_Date_Exception 4124 */ 4125 public function addDayOfYear($day, $locale = null) 4126 { 4127 return $this->_calcvalue('add', $day, 'day of year', self::DAY_OF_YEAR, $locale); 4128 } 4129 4130 4131 /** 4132 * Subtracts a day of year from the existing date object. 4133 * The day of year is always a number. 4134 * Returned is the new date object 4135 * Example: subDayOfYear(10); will subtract 10 days from the existing date object. 4136 * 4137 * @param string|integer|array|Zend_Date $day Day of Year to sub 4138 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4139 * @return Zend_Date Provides fluid interface 4140 * @throws Zend_Date_Exception 4141 */ 4142 public function subDayOfYear($day, $locale = null) 4143 { 4144 return $this->_calcvalue('sub', $day, 'day of year', self::DAY_OF_YEAR, $locale); 4145 } 4146 4147 4148 /** 4149 * Compares the day of year with the existing date object. 4150 * For example: compareDayOfYear(33) -> 02.Feb.2007 -> 0 4151 * Returns if equal, earlier or later 4152 * 4153 * @param string|integer|array|Zend_Date $day Day of Year to compare 4154 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4155 * @return integer 0 = equal, 1 = later, -1 = earlier 4156 * @throws Zend_Date_Exception 4157 */ 4158 public function compareDayOfYear($day, $locale = null) 4159 { 4160 return $this->_calcvalue('cmp', $day, 'day of year', self::DAY_OF_YEAR, $locale); 4161 } 4162 4163 4164 /** 4165 * Returns the hour as new date object 4166 * Example: 02.Feb.1986 10:30:25 -> 01.Jan.1970 10:00:00 4167 * 4168 * @param $locale string|Zend_Locale OPTIONAL Locale for parsing input 4169 * @return Zend_Date 4170 */ 4171 public function getHour($locale = null) 4172 { 4173 return $this->copyPart(self::HOUR, $locale); 4174 } 4175 4176 4177 /** 4178 * Sets a new hour 4179 * The hour is always a number. 4180 * Returned is the new date object 4181 * Example: 04.May.1993 13:07:25 -> setHour(7); -> 04.May.1993 07:07:25 4182 * 4183 * @param string|integer|array|Zend_Date $hour Hour to set 4184 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4185 * @return Zend_Date Provides fluid interface 4186 * @throws Zend_Date_Exception 4187 */ 4188 public function setHour($hour, $locale = null) 4189 { 4190 return $this->_calcvalue('set', $hour, 'hour', self::HOUR_SHORT, $locale); 4191 } 4192 4193 4194 /** 4195 * Adds hours to the existing date object. 4196 * The hour is always a number. 4197 * Returned is the new date object 4198 * Example: 04.May.1993 13:07:25 -> addHour(12); -> 05.May.1993 01:07:25 4199 * 4200 * @param string|integer|array|Zend_Date $hour Hour to add 4201 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4202 * @return Zend_Date Provides fluid interface 4203 * @throws Zend_Date_Exception 4204 */ 4205 public function addHour($hour, $locale = null) 4206 { 4207 return $this->_calcvalue('add', $hour, 'hour', self::HOUR_SHORT, $locale); 4208 } 4209 4210 4211 /** 4212 * Subtracts hours from the existing date object. 4213 * The hour is always a number. 4214 * Returned is the new date object 4215 * Example: 04.May.1993 13:07:25 -> subHour(6); -> 05.May.1993 07:07:25 4216 * 4217 * @param string|integer|array|Zend_Date $hour Hour to sub 4218 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4219 * @return Zend_Date Provides fluid interface 4220 * @throws Zend_Date_Exception 4221 */ 4222 public function subHour($hour, $locale = null) 4223 { 4224 return $this->_calcvalue('sub', $hour, 'hour', self::HOUR_SHORT, $locale); 4225 } 4226 4227 4228 /** 4229 * Compares the hour with the existing date object. 4230 * For example: 10:30:25 -> compareHour(10) -> 0 4231 * Returns if equal, earlier or later 4232 * 4233 * @param string|integer|array|Zend_Date $hour Hour to compare 4234 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4235 * @return integer 0 = equal, 1 = later, -1 = earlier 4236 * @throws Zend_Date_Exception 4237 */ 4238 public function compareHour($hour, $locale = null) 4239 { 4240 return $this->_calcvalue('cmp', $hour, 'hour', self::HOUR_SHORT, $locale); 4241 } 4242 4243 4244 /** 4245 * Returns the minute as new date object 4246 * Example: 02.Feb.1986 10:30:25 -> 01.Jan.1970 00:30:00 4247 * 4248 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4249 * @return Zend_Date 4250 */ 4251 public function getMinute($locale = null) 4252 { 4253 if (self::$_options['format_type'] == 'php') { 4254 $format = 'i'; 4255 } else { 4256 $format = self::MINUTE; 4257 } 4258 4259 return $this->copyPart($format, $locale); 4260 } 4261 4262 4263 /** 4264 * Sets a new minute 4265 * The minute is always a number. 4266 * Returned is the new date object 4267 * Example: 04.May.1993 13:07:25 -> setMinute(29); -> 04.May.1993 13:29:25 4268 * 4269 * @param string|integer|array|Zend_Date $minute Minute to set 4270 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4271 * @return Zend_Date Provides fluid interface 4272 * @throws Zend_Date_Exception 4273 */ 4274 public function setMinute($minute, $locale = null) 4275 { 4276 return $this->_calcvalue('set', $minute, 'minute', self::MINUTE_SHORT, $locale); 4277 } 4278 4279 4280 /** 4281 * Adds minutes to the existing date object. 4282 * The minute is always a number. 4283 * Returned is the new date object 4284 * Example: 04.May.1993 13:07:25 -> addMinute(65); -> 04.May.1993 13:12:25 4285 * 4286 * @param string|integer|array|Zend_Date $minute Minute to add 4287 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4288 * @return Zend_Date Provides fluid interface 4289 * @throws Zend_Date_Exception 4290 */ 4291 public function addMinute($minute, $locale = null) 4292 { 4293 return $this->_calcvalue('add', $minute, 'minute', self::MINUTE_SHORT, $locale); 4294 } 4295 4296 4297 /** 4298 * Subtracts minutes from the existing date object. 4299 * The minute is always a number. 4300 * Returned is the new date object 4301 * Example: 04.May.1993 13:07:25 -> subMinute(9); -> 04.May.1993 12:58:25 4302 * 4303 * @param string|integer|array|Zend_Date $minute Minute to sub 4304 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4305 * @return Zend_Date Provides fluid interface 4306 * @throws Zend_Date_Exception 4307 */ 4308 public function subMinute($minute, $locale = null) 4309 { 4310 return $this->_calcvalue('sub', $minute, 'minute', self::MINUTE_SHORT, $locale); 4311 } 4312 4313 4314 /** 4315 * Compares the minute with the existing date object. 4316 * For example: 10:30:25 -> compareMinute(30) -> 0 4317 * Returns if equal, earlier or later 4318 * 4319 * @param string|integer|array|Zend_Date $minute Hour to compare 4320 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4321 * @return integer 0 = equal, 1 = later, -1 = earlier 4322 * @throws Zend_Date_Exception 4323 */ 4324 public function compareMinute($minute, $locale = null) 4325 { 4326 return $this->_calcvalue('cmp', $minute, 'minute', self::MINUTE_SHORT, $locale); 4327 } 4328 4329 4330 /** 4331 * Returns the second as new date object 4332 * Example: 02.Feb.1986 10:30:25 -> 01.Jan.1970 00:00:25 4333 * 4334 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4335 * @return Zend_Date 4336 */ 4337 public function getSecond($locale = null) 4338 { 4339 if (self::$_options['format_type'] == 'php') { 4340 $format = 's'; 4341 } else { 4342 $format = self::SECOND; 4343 } 4344 4345 return $this->copyPart($format, $locale); 4346 } 4347 4348 4349 /** 4350 * Sets new seconds to the existing date object. 4351 * The second is always a number. 4352 * Returned is the new date object 4353 * Example: 04.May.1993 13:07:25 -> setSecond(100); -> 04.May.1993 13:08:40 4354 * 4355 * @param string|integer|array|Zend_Date $second Second to set 4356 * @param string|Zend_Locale $locale (Optional) Locale for parsing input 4357 * @return Zend_Date Provides fluid interface 4358 * @throws Zend_Date_Exception 4359 */ 4360 public function setSecond($second, $locale = null) 4361 { 4362 return $this->_calcvalue('set', $second, 'second', self::SECOND_SHORT, $locale); 4363 } 4364 4365 4366 /** 4367 * Adds seconds to the existing date object. 4368 * The second is always a number. 4369 * Returned is the new date object 4370 * Example: 04.May.1993 13:07:25 -> addSecond(65); -> 04.May.1993 13:08:30 4371 * 4372 * @param string|integer|array|Zend_Date $second Second to add 4373 * @param string|Zend_Locale $locale (Optional) Locale for parsing input 4374 * @return Zend_Date Provides fluid interface 4375 * @throws Zend_Date_Exception 4376 */ 4377 public function addSecond($second, $locale = null) 4378 { 4379 return $this->_calcvalue('add', $second, 'second', self::SECOND_SHORT, $locale); 4380 } 4381 4382 4383 /** 4384 * Subtracts seconds from the existing date object. 4385 * The second is always a number. 4386 * Returned is the new date object 4387 * Example: 04.May.1993 13:07:25 -> subSecond(10); -> 04.May.1993 13:07:15 4388 * 4389 * @param string|integer|array|Zend_Date $second Second to sub 4390 * @param string|Zend_Locale $locale (Optional) Locale for parsing input 4391 * @return Zend_Date Provides fluid interface 4392 * @throws Zend_Date_Exception 4393 */ 4394 public function subSecond($second, $locale = null) 4395 { 4396 return $this->_calcvalue('sub', $second, 'second', self::SECOND_SHORT, $locale); 4397 } 4398 4399 4400 /** 4401 * Compares the second with the existing date object. 4402 * For example: 10:30:25 -> compareSecond(25) -> 0 4403 * Returns if equal, earlier or later 4404 * 4405 * @param string|integer|array|Zend_Date $second Second to compare 4406 * @param string|Zend_Locale $locale (Optional) Locale for parsing input 4407 * @return integer 0 = equal, 1 = later, -1 = earlier 4408 * @throws Zend_Date_Exception 4409 */ 4410 public function compareSecond($second, $locale = null) 4411 { 4412 return $this->_calcvalue('cmp', $second, 'second', self::SECOND_SHORT, $locale); 4413 } 4414 4415 4416 /** 4417 * Returns the precision for fractional seconds 4418 * 4419 * @return integer 4420 */ 4421 public function getFractionalPrecision() 4422 { 4423 return $this->_precision; 4424 } 4425 4426 4427 /** 4428 * Sets a new precision for fractional seconds 4429 * 4430 * @param integer $precision Precision for the fractional datepart 3 = milliseconds 4431 * @throws Zend_Date_Exception 4432 * @return Zend_Date Provides fluid interface 4433 */ 4434 public function setFractionalPrecision($precision) 4435 { 4436 if (!intval($precision) or ($precision < 0) or ($precision > 9)) { 4437 require_once 'Zend/Date/Exception.php'; 4438 throw new Zend_Date_Exception("precision ($precision) must be a positive integer less than 10", 0, null, $precision); 4439 } 4440 4441 $this->_precision = (int) $precision; 4442 if ($this->_precision < strlen($this->_fractional)) { 4443 $this->_fractional = substr($this->_fractional, 0, $this->_precision); 4444 } else { 4445 $this->_fractional = str_pad($this->_fractional, $this->_precision, '0', STR_PAD_RIGHT); 4446 } 4447 4448 return $this; 4449 } 4450 4451 4452 /** 4453 * Returns the milliseconds of the date object 4454 * 4455 * @return string 4456 */ 4457 public function getMilliSecond() 4458 { 4459 return $this->_fractional; 4460 } 4461 4462 4463 /** 4464 * Sets new milliseconds for the date object 4465 * Example: setMilliSecond(550, 2) -> equals +5 Sec +50 MilliSec 4466 * 4467 * @param integer|Zend_Date $milli (Optional) Millisecond to set, when null the actual millisecond is set 4468 * @param integer $precision (Optional) Fraction precision of the given milliseconds 4469 * @return Zend_Date Provides fluid interface 4470 */ 4471 public function setMilliSecond($milli = null, $precision = null) 4472 { 4473 if ($milli === null) { 4474 list($milli, $time) = explode(" ", microtime()); 4475 $milli = intval($milli); 4476 $precision = 6; 4477 } else if (!is_numeric($milli)) { 4478 require_once 'Zend/Date/Exception.php'; 4479 throw new Zend_Date_Exception("invalid milli second ($milli) operand", 0, null, $milli); 4480 } 4481 4482 if ($precision === null) { 4483 $precision = $this->_precision; 4484 } 4485 4486 if (!is_int($precision) || $precision < 1 || $precision > 9) { 4487 require_once 'Zend/Date/Exception.php'; 4488 throw new Zend_Date_Exception("precision ($precision) must be a positive integer less than 10", 0, null, $precision); 4489 } 4490 4491 $this->_fractional = 0; 4492 $this->addMilliSecond($milli, $precision); 4493 return $this; 4494 } 4495 4496 4497 /** 4498 * Adds milliseconds to the date object 4499 * 4500 * @param integer|Zend_Date $milli (Optional) Millisecond to add, when null the actual millisecond is added 4501 * @param integer $precision (Optional) Fractional precision for the given milliseconds 4502 * @return Zend_Date Provides fluid interface 4503 */ 4504 public function addMilliSecond($milli = null, $precision = null) 4505 { 4506 if ($milli === null) { 4507 list($milli, $time) = explode(" ", microtime()); 4508 $milli = intval($milli); 4509 } else if (!is_numeric($milli)) { 4510 require_once 'Zend/Date/Exception.php'; 4511 throw new Zend_Date_Exception("invalid milli second ($milli) operand", 0, null, $milli); 4512 } 4513 4514 if ($precision === null) { 4515 $precision = strlen($milli); 4516 if ($milli < 0) { 4517 --$precision; 4518 } 4519 } 4520 4521 if (!is_int($precision) || $precision < 1 || $precision > 9) { 4522 require_once 'Zend/Date/Exception.php'; 4523 throw new Zend_Date_Exception("precision ($precision) must be a positive integer less than 10", 0, null, $precision); 4524 } 4525 4526 $this->_fractional += $milli; 4527 4528 // Add/sub milliseconds + add/sub seconds 4529 $max = pow(10, $this->_precision); 4530 // Milli includes seconds 4531 if ($this->_fractional >= $max) { 4532 while ($this->_fractional >= $max) { 4533 $this->addSecond(1); 4534 $this->_fractional -= $max; 4535 } 4536 } 4537 4538 if ($this->_fractional < 0) { 4539 while ($this->_fractional < 0) { 4540 $this->subSecond(1); 4541 $this->_fractional += $max; 4542 } 4543 } 4544 4545 if ($this->_precision > strlen($this->_fractional)) { 4546 $this->_fractional = str_pad($this->_fractional, $this->_precision, '0', STR_PAD_LEFT); 4547 } 4548 4549 return $this; 4550 } 4551 4552 4553 /** 4554 * Subtracts a millisecond 4555 * 4556 * @param integer|Zend_Date $milli (Optional) Millisecond to sub, when null the actual millisecond is subtracted 4557 * @param integer $precision (Optional) Fractional precision for the given milliseconds 4558 * @return Zend_Date Provides fluid interface 4559 */ 4560 public function subMilliSecond($milli = null, $precision = null) 4561 { 4562 $this->addMilliSecond(0 - $milli, $precision); 4563 return $this; 4564 } 4565 4566 /** 4567 * Compares only the millisecond part, returning the difference 4568 * 4569 * @param integer|Zend_Date $milli OPTIONAL Millisecond to compare, when null the actual millisecond is compared 4570 * @param integer $precision OPTIONAL Fractional precision for the given milliseconds 4571 * @throws Zend_Date_Exception On invalid input 4572 * @return integer 0 = equal, 1 = later, -1 = earlier 4573 */ 4574 public function compareMilliSecond($milli = null, $precision = null) 4575 { 4576 if ($milli === null) { 4577 list($milli, $time) = explode(" ", microtime()); 4578 $milli = intval($milli); 4579 } else if (is_numeric($milli) === false) { 4580 require_once 'Zend/Date/Exception.php'; 4581 throw new Zend_Date_Exception("invalid milli second ($milli) operand", 0, null, $milli); 4582 } 4583 4584 if ($precision === null) { 4585 $precision = strlen($milli); 4586 } else if (!is_int($precision) || $precision < 1 || $precision > 9) { 4587 require_once 'Zend/Date/Exception.php'; 4588 throw new Zend_Date_Exception("precision ($precision) must be a positive integer less than 10", 0, null, $precision); 4589 } 4590 4591 if ($precision === 0) { 4592 require_once 'Zend/Date/Exception.php'; 4593 throw new Zend_Date_Exception('precision is 0'); 4594 } 4595 4596 if ($precision != $this->_precision) { 4597 if ($precision > $this->_precision) { 4598 $diff = $precision - $this->_precision; 4599 $milli = (int) ($milli / (10 * $diff)); 4600 } else { 4601 $diff = $this->_precision - $precision; 4602 $milli = (int) ($milli * (10 * $diff)); 4603 } 4604 } 4605 4606 $comp = $this->_fractional - $milli; 4607 if ($comp < 0) { 4608 return -1; 4609 } else if ($comp > 0) { 4610 return 1; 4611 } 4612 return 0; 4613 } 4614 4615 /** 4616 * Returns the week as new date object using monday as begining of the week 4617 * Example: 12.Jan.2007 -> 08.Jan.1970 00:00:00 4618 * 4619 * @param $locale string|Zend_Locale OPTIONAL Locale for parsing input 4620 * @return Zend_Date 4621 */ 4622 public function getWeek($locale = null) 4623 { 4624 if (self::$_options['format_type'] == 'php') { 4625 $format = 'W'; 4626 } else { 4627 $format = self::WEEK; 4628 } 4629 4630 return $this->copyPart($format, $locale); 4631 } 4632 4633 /** 4634 * Sets a new week. The week is always a number. The day of week is not changed. 4635 * Returned is the new date object 4636 * Example: 09.Jan.2007 13:07:25 -> setWeek(1); -> 02.Jan.2007 13:07:25 4637 * 4638 * @param string|integer|array|Zend_Date $week Week to set 4639 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4640 * @return Zend_Date Provides fluid interface 4641 * @throws Zend_Date_Exception 4642 */ 4643 public function setWeek($week, $locale = null) 4644 { 4645 return $this->_calcvalue('set', $week, 'week', self::WEEK, $locale); 4646 } 4647 4648 /** 4649 * Adds a week. The week is always a number. The day of week is not changed. 4650 * Returned is the new date object 4651 * Example: 09.Jan.2007 13:07:25 -> addWeek(1); -> 16.Jan.2007 13:07:25 4652 * 4653 * @param string|integer|array|Zend_Date $week Week to add 4654 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4655 * @return Zend_Date Provides fluid interface 4656 * @throws Zend_Date_Exception 4657 */ 4658 public function addWeek($week, $locale = null) 4659 { 4660 return $this->_calcvalue('add', $week, 'week', self::WEEK, $locale); 4661 } 4662 4663 /** 4664 * Subtracts a week. The week is always a number. The day of week is not changed. 4665 * Returned is the new date object 4666 * Example: 09.Jan.2007 13:07:25 -> subWeek(1); -> 02.Jan.2007 13:07:25 4667 * 4668 * @param string|integer|array|Zend_Date $week Week to sub 4669 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4670 * @return Zend_Date Provides fluid interface 4671 * @throws Zend_Date_Exception 4672 */ 4673 public function subWeek($week, $locale = null) 4674 { 4675 return $this->_calcvalue('sub', $week, 'week', self::WEEK, $locale); 4676 } 4677 4678 /** 4679 * Compares only the week part, returning the difference 4680 * Returned is the new date object 4681 * Returns if equal, earlier or later 4682 * Example: 09.Jan.2007 13:07:25 -> compareWeek(2); -> 0 4683 * 4684 * @param string|integer|array|Zend_Date $week Week to compare 4685 * @param string|Zend_Locale $locale OPTIONAL Locale for parsing input 4686 * @return integer 0 = equal, 1 = later, -1 = earlier 4687 */ 4688 public function compareWeek($week, $locale = null) 4689 { 4690 return $this->_calcvalue('cmp', $week, 'week', self::WEEK, $locale); 4691 } 4692 4693 /** 4694 * Sets a new standard locale for the date object. 4695 * This locale will be used for all functions 4696 * Returned is the really set locale. 4697 * Example: 'de_XX' will be set to 'de' because 'de_XX' does not exist 4698 * 'xx_YY' will be set to 'root' because 'xx' does not exist 4699 * 4700 * @param string|Zend_Locale $locale (Optional) Locale for parsing input 4701 * @throws Zend_Date_Exception When the given locale does not exist 4702 * @return Zend_Date Provides fluent interface 4703 */ 4704 public function setLocale($locale = null) 4705 { 4706 try { 4707 $this->_locale = Zend_Locale::findLocale($locale); 4708 } catch (Zend_Locale_Exception $e) { 4709 require_once 'Zend/Date/Exception.php'; 4710 throw new Zend_Date_Exception($e->getMessage(), 0, $e); 4711 } 4712 4713 return $this; 4714 } 4715 4716 /** 4717 * Returns the actual set locale 4718 * 4719 * @return string 4720 */ 4721 public function getLocale() 4722 { 4723 return $this->_locale; 4724 } 4725 4726 /** 4727 * Checks if the given date is a real date or datepart. 4728 * Returns false if a expected datepart is missing or a datepart exceeds its possible border. 4729 * But the check will only be done for the expected dateparts which are given by format. 4730 * If no format is given the standard dateformat for the actual locale is used. 4731 * f.e. 30.February.2007 will return false if format is 'dd.MMMM.YYYY' 4732 * 4733 * @param string|array|Zend_Date $date Date to parse for correctness 4734 * @param string $format (Optional) Format for parsing the date string 4735 * @param string|Zend_Locale $locale (Optional) Locale for parsing date parts 4736 * @return boolean True when all date parts are correct 4737 */ 4738 public static function isDate($date, $format = null, $locale = null) 4739 { 4740 if (!is_string($date) && !is_numeric($date) && !($date instanceof Zend_Date) && 4741 !is_array($date)) { 4742 return false; 4743 } 4744 4745 if (($format !== null) && ($format != 'ee') && ($format != 'ss') && ($format != 'GG') && ($format != 'MM') && ($format != 'EE') && ($format != 'TT') 4746 && (Zend_Locale::isLocale($format, null, false))) { 4747 $locale = $format; 4748 $format = null; 4749 } 4750 4751 $locale = Zend_Locale::findLocale($locale); 4752 4753 if ($format === null) { 4754 $format = Zend_Locale_Format::getDateFormat($locale); 4755 } else if ((self::$_options['format_type'] == 'php') && !defined($format)) { 4756 $format = Zend_Locale_Format::convertPhpToIsoFormat($format); 4757 } 4758 4759 $format = self::_getLocalizedToken($format, $locale); 4760 if (!is_array($date)) { 4761 try { 4762 $parsed = Zend_Locale_Format::getDate($date, array('locale' => $locale, 4763 'date_format' => $format, 'format_type' => 'iso', 4764 'fix_date' => false)); 4765 } catch (Zend_Locale_Exception $e) { 4766 // Date can not be parsed 4767 return false; 4768 } 4769 } else { 4770 $parsed = $date; 4771 } 4772 4773 if (((strpos($format, 'Y') !== false) or (strpos($format, 'y') !== false)) and 4774 (!isset($parsed['year']))) { 4775 // Year expected but not found 4776 return false; 4777 } 4778 4779 if ((strpos($format, 'M') !== false) and (!isset($parsed['month']))) { 4780 // Month expected but not found 4781 return false; 4782 } 4783 4784 if ((strpos($format, 'd') !== false) and (!isset($parsed['day']))) { 4785 // Day expected but not found 4786 return false; 4787 } 4788 4789 if (((strpos($format, 'H') !== false) or (strpos($format, 'h') !== false)) and 4790 (!isset($parsed['hour']))) { 4791 // Hour expected but not found 4792 return false; 4793 } 4794 4795 if ((strpos($format, 'm') !== false) and (!isset($parsed['minute']))) { 4796 // Minute expected but not found 4797 return false; 4798 } 4799 4800 if ((strpos($format, 's') !== false) and (!isset($parsed['second']))) { 4801 // Second expected but not found 4802 return false; 4803 } 4804 4805 // Set not given dateparts 4806 if (isset($parsed['hour']) === false) { 4807 $parsed['hour'] = 12; 4808 } 4809 4810 if (isset($parsed['minute']) === false) { 4811 $parsed['minute'] = 0; 4812 } 4813 4814 if (isset($parsed['second']) === false) { 4815 $parsed['second'] = 0; 4816 } 4817 4818 if (isset($parsed['month']) === false) { 4819 $parsed['month'] = 1; 4820 } 4821 4822 if (isset($parsed['day']) === false) { 4823 $parsed['day'] = 1; 4824 } 4825 4826 if (isset($parsed['year']) === false) { 4827 $parsed['year'] = 1970; 4828 } 4829 4830 if (self::isYearLeapYear($parsed['year'])) { 4831 $parsed['year'] = 1972; 4832 } else { 4833 $parsed['year'] = 1971; 4834 } 4835 4836 $date = new self($parsed, null, $locale); 4837 $timestamp = $date->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 4838 $parsed['month'], $parsed['day'], $parsed['year']); 4839 4840 if ($parsed['year'] != $date->date('Y', $timestamp)) { 4841 // Given year differs from parsed year 4842 return false; 4843 } 4844 4845 if ($parsed['month'] != $date->date('n', $timestamp)) { 4846 // Given month differs from parsed month 4847 return false; 4848 } 4849 4850 if ($parsed['day'] != $date->date('j', $timestamp)) { 4851 // Given day differs from parsed day 4852 return false; 4853 } 4854 4855 if ($parsed['hour'] != $date->date('G', $timestamp)) { 4856 // Given hour differs from parsed hour 4857 return false; 4858 } 4859 4860 if ($parsed['minute'] != $date->date('i', $timestamp)) { 4861 // Given minute differs from parsed minute 4862 return false; 4863 } 4864 4865 if ($parsed['second'] != $date->date('s', $timestamp)) { 4866 // Given second differs from parsed second 4867 return false; 4868 } 4869 4870 return true; 4871 } 4872 4873 /** 4874 * Returns the ISO Token for all localized constants 4875 * 4876 * @param string $token Token to normalize 4877 * @param string $locale Locale to search 4878 * @return string 4879 */ 4880 protected static function _getLocalizedToken($token, $locale) 4881 { 4882 switch($token) { 4883 case self::ISO_8601 : 4884 return "yyyy-MM-ddThh:mm:ss"; 4885 break; 4886 case self::RFC_2822 : 4887 return "EEE, dd MMM yyyy HH:mm:ss"; 4888 break; 4889 case self::DATES : 4890 return Zend_Locale_Data::getContent($locale, 'date'); 4891 break; 4892 case self::DATE_FULL : 4893 return Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'full')); 4894 break; 4895 case self::DATE_LONG : 4896 return Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'long')); 4897 break; 4898 case self::DATE_MEDIUM : 4899 return Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'medium')); 4900 break; 4901 case self::DATE_SHORT : 4902 return Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'short')); 4903 break; 4904 case self::TIMES : 4905 return Zend_Locale_Data::getContent($locale, 'time'); 4906 break; 4907 case self::TIME_FULL : 4908 return Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'full')); 4909 break; 4910 case self::TIME_LONG : 4911 return Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'long')); 4912 break; 4913 case self::TIME_MEDIUM : 4914 return Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'medium')); 4915 break; 4916 case self::TIME_SHORT : 4917 return Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'short')); 4918 break; 4919 case self::DATETIME : 4920 return Zend_Locale_Data::getContent($locale, 'datetime'); 4921 break; 4922 case self::DATETIME_FULL : 4923 return Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'full')); 4924 break; 4925 case self::DATETIME_LONG : 4926 return Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'long')); 4927 break; 4928 case self::DATETIME_MEDIUM : 4929 return Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'medium')); 4930 break; 4931 case self::DATETIME_SHORT : 4932 return Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'short')); 4933 break; 4934 case self::ATOM : 4935 case self::RFC_3339 : 4936 case self::W3C : 4937 return "yyyy-MM-DD HH:mm:ss"; 4938 break; 4939 case self::COOKIE : 4940 case self::RFC_850 : 4941 return "EEEE, dd-MM-yyyy HH:mm:ss"; 4942 break; 4943 case self::RFC_822 : 4944 case self::RFC_1036 : 4945 case self::RFC_1123 : 4946 case self::RSS : 4947 return "EEE, dd MM yyyy HH:mm:ss"; 4948 break; 4949 } 4950 4951 return $token; 4952 } 4953 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |