Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/zend/Zend/Date.php
Go to the documentation of this file.
00001 <?php
00025 require_once 'Zend/Date/DateObject.php';
00026 require_once 'Zend/Locale.php';
00027 require_once 'Zend/Locale/Format.php';
00028 require_once 'Zend/Locale/Math.php';
00029 
00036 class Zend_Date extends Zend_Date_DateObject
00037 {
00038     private $_locale  = null;
00039 
00040     // Fractional second variables
00041     private $_fractional = 0;
00042     private $_precision  = 3;
00043 
00044     private static $_options = array(
00045         'format_type'  => 'iso',      // format for date strings 'iso' or 'php'
00046         'fix_dst'      => true,       // fix dst on summer/winter time change
00047         'extend_month' => false,      // false - addMonth like SQL, true like excel
00048         'cache'        => null,       // cache to set
00049         'timesync'     => null        // timesync server to set
00050     );
00051 
00052     // Class wide Date Constants
00053     const DAY               = 'dd';
00054     const DAY_SHORT         = 'd';
00055     const DAY_SUFFIX        = 'SS';
00056     const DAY_OF_YEAR       = 'D';
00057     const WEEKDAY           = 'EEEE';
00058     const WEEKDAY_SHORT     = 'EEE';
00059     const WEEKDAY_NARROW    = 'E';
00060     const WEEKDAY_NAME      = 'EE';
00061     const WEEKDAY_8601      = 'eee';
00062     const WEEKDAY_DIGIT     = 'e';
00063     const WEEK              = 'ww';
00064     const MONTH             = 'MM';
00065     const MONTH_SHORT       = 'M';
00066     const MONTH_DAYS        = 'ddd';
00067     const MONTH_NAME        = 'MMMM';
00068     const MONTH_NAME_SHORT  = 'MMM';
00069     const MONTH_NAME_NARROW = 'MMMMM';
00070     const YEAR              = 'y';
00071     const YEAR_SHORT        = 'yy';
00072     const YEAR_8601         = 'Y';
00073     const YEAR_SHORT_8601   = 'YY';
00074     const LEAPYEAR          = 'l';
00075     const MERIDIEM          = 'a';
00076     const SWATCH            = 'B';
00077     const HOUR              = 'HH';
00078     const HOUR_SHORT        = 'H';
00079     const HOUR_AM           = 'hh';
00080     const HOUR_SHORT_AM     = 'h';
00081     const MINUTE            = 'mm';
00082     const MINUTE_SHORT      = 'm';
00083     const SECOND            = 'ss';
00084     const SECOND_SHORT      = 's';
00085     const MILLISECOND       = 'S';
00086     const TIMEZONE_NAME     = 'zzzz';
00087     const DAYLIGHT          = 'I';
00088     const GMT_DIFF          = 'Z';
00089     const GMT_DIFF_SEP      = 'ZZZZ';
00090     const TIMEZONE          = 'z';
00091     const TIMEZONE_SECS     = 'X';
00092     const ISO_8601          = 'c';
00093     const RFC_2822          = 'r';
00094     const TIMESTAMP         = 'U';
00095     const ERA               = 'G';
00096     const ERA_NAME          = 'GGGG';
00097     const ERA_NARROW        = 'GGGGG';
00098     const DATES             = 'F';
00099     const DATE_FULL         = 'FFFFF';
00100     const DATE_LONG         = 'FFFF';
00101     const DATE_MEDIUM       = 'FFF';
00102     const DATE_SHORT        = 'FF';
00103     const TIMES             = 'WW';
00104     const TIME_FULL         = 'TTTTT';
00105     const TIME_LONG         = 'TTTT';
00106     const TIME_MEDIUM       = 'TTT';
00107     const TIME_SHORT        = 'TT';
00108     const DATETIME          = 'K';
00109     const DATETIME_FULL     = 'KKKKK';
00110     const DATETIME_LONG     = 'KKKK';
00111     const DATETIME_MEDIUM   = 'KKK';
00112     const DATETIME_SHORT    = 'KK';
00113     const ATOM              = 'OOO';
00114     const COOKIE            = 'CCC';
00115     const RFC_822           = 'R';
00116     const RFC_850           = 'RR';
00117     const RFC_1036          = 'RRR';
00118     const RFC_1123          = 'RRRR';
00119     const RFC_3339          = 'RRRRR';
00120     const RSS               = 'SSS';
00121     const W3C               = 'WWW';
00122 
00137     public function __construct($date = null, $part = null, $locale = null)
00138     {
00139         if (is_object($date) and !($date instanceof Zend_TimeSync_Protocol) and
00140             !($date instanceof Zend_Date)) {
00141             if ($locale instanceof Zend_Locale) {
00142                 $locale = $date;
00143                 $date   = null;
00144                 $part   = null;
00145             } else {
00146                 $date = (string) $date;
00147             }
00148         }
00149 
00150         if (($date !== null) and !is_array($date) and !($date instanceof Zend_TimeSync_Protocol) and
00151             !($date instanceof Zend_Date) and !defined($date) and Zend_Locale::isLocale($date, true, false)) {
00152             $locale = $date;
00153             $date   = null;
00154             $part   = null;
00155         } else if (($part !== null) and !defined($part) and Zend_Locale::isLocale($part, true, false)) {
00156             $locale = $part;
00157             $part   = null;
00158         }
00159 
00160         $this->setLocale($locale);
00161         if (is_string($date) && ($part === null) && (strlen($date) <= 5)) {
00162             $part = $date;
00163             $date = null;
00164         }
00165 
00166         if ($date === null) {
00167             if ($part === null) {
00168                 $date = time();
00169             } else if ($part !== self::TIMESTAMP) {
00170                 $date = self::now($locale);
00171                 $date = $date->get($part);
00172             }
00173         }
00174 
00175         if ($date instanceof Zend_TimeSync_Protocol) {
00176             $date = $date->getInfo();
00177             $date = $this->_getTime($date['offset']);
00178             $part = null;
00179         } else if (parent::$_defaultOffset != 0) {
00180             $date = $this->_getTime(parent::$_defaultOffset);
00181         }
00182 
00183         // set the timezone and offset for $this
00184         $zone = @date_default_timezone_get();
00185         $this->setTimezone($zone);
00186 
00187         // try to get timezone from date-string
00188         if (!is_int($date)) {
00189             $zone = $this->getTimezoneFromString($date);
00190             $this->setTimezone($zone);
00191         }
00192 
00193         // set datepart
00194         if (($part !== null && $part !== self::TIMESTAMP) or (!is_numeric($date))) {
00195             // switch off dst handling for value setting
00196             $this->setUnixTimestamp($this->getGmtOffset());
00197             $this->set($date, $part, $this->_locale);
00198 
00199             // DST fix
00200             if (is_array($date) === true) {
00201                 if (!isset($date['hour'])) {
00202                     $date['hour'] = 0;
00203                 }
00204 
00205                 $hour = $this->toString('H', 'iso', true);
00206                 $hour = $date['hour'] - $hour;
00207                 switch ($hour) {
00208                     case 1 :
00209                     case -23 :
00210                         $this->addTimestamp(3600);
00211                         break;
00212                     case -1 :
00213                     case 23 :
00214                         $this->subTimestamp(3600);
00215                         break;
00216                     case 2 :
00217                     case -22 :
00218                         $this->addTimestamp(7200);
00219                         break;
00220                     case -2 :
00221                     case 22 :
00222                         $this->subTimestamp(7200);
00223                         break;
00224                 }
00225             }
00226         } else {
00227             $this->setUnixTimestamp($date);
00228         }
00229     }
00230 
00238     public static function setOptions(array $options = array())
00239     {
00240         if (empty($options)) {
00241             return self::$_options;
00242         }
00243 
00244         foreach ($options as $name => $value) {
00245             $name  = strtolower($name);
00246 
00247             if (array_key_exists($name, self::$_options)) {
00248                 switch($name) {
00249                     case 'format_type' :
00250                         if ((strtolower($value) != 'php') && (strtolower($value) != 'iso')) {
00251                             require_once 'Zend/Date/Exception.php';
00252                             throw new Zend_Date_Exception("Unknown format type ($value) for dates, only 'iso' and 'php' supported", 0, null, $value);
00253                         }
00254                         break;
00255                     case 'fix_dst' :
00256                         if (!is_bool($value)) {
00257                             require_once 'Zend/Date/Exception.php';
00258                             throw new Zend_Date_Exception("'fix_dst' has to be boolean", 0, null, $value);
00259                         }
00260                         break;
00261                     case 'extend_month' :
00262                         if (!is_bool($value)) {
00263                             require_once 'Zend/Date/Exception.php';
00264                             throw new Zend_Date_Exception("'extend_month' has to be boolean", 0, null, $value);
00265                         }
00266                         break;
00267                     case 'cache' :
00268                         if ($value === null) {
00269                             parent::$_cache = null;
00270                         } else {
00271                             if (!$value instanceof Zend_Cache_Core) {
00272                                 require_once 'Zend/Date/Exception.php';
00273                                 throw new Zend_Date_Exception("Instance of Zend_Cache expected");
00274                             }
00275 
00276                             parent::$_cache = $value;
00277                             Zend_Locale_Data::setCache($value);
00278                         }
00279                         break;
00280                     case 'timesync' :
00281                         if ($value === null) {
00282                             parent::$_defaultOffset = 0;
00283                         } else {
00284                             if (!$value instanceof Zend_TimeSync_Protocol) {
00285                                 require_once 'Zend/Date/Exception.php';
00286                                 throw new Zend_Date_Exception("Instance of Zend_TimeSync expected");
00287                             }
00288 
00289                             $date = $value->getInfo();
00290                             parent::$_defaultOffset = $date['offset'];
00291                         }
00292                         break;
00293                 }
00294                 self::$_options[$name] = $value;
00295             }
00296             else {
00297                 require_once 'Zend/Date/Exception.php';
00298                 throw new Zend_Date_Exception("Unknown option: $name = $value");
00299             }
00300         }
00301     }
00302 
00311     public function getTimestamp()
00312     {
00313         return $this->getUnixTimestamp();
00314     }
00315 
00325     private function _timestamp($calc, $stamp)
00326     {
00327         if ($stamp instanceof Zend_Date) {
00328             // extract timestamp from object
00329             $stamp = $stamp->getTimestamp();
00330         }
00331 
00332         if (is_array($stamp)) {
00333             if (isset($stamp['timestamp']) === true) {
00334                 $stamp = $stamp['timestamp'];
00335             } else {
00336                 require_once 'Zend/Date/Exception.php';
00337                 throw new Zend_Date_Exception('no timestamp given in array');
00338             }
00339         }
00340 
00341         if ($calc === 'set') {
00342             $return = $this->setUnixTimestamp($stamp);
00343         } else {
00344             $return = $this->_calcdetail($calc, $stamp, self::TIMESTAMP, null);
00345         }
00346         if ($calc != 'cmp') {
00347             return $this;
00348         }
00349         return $return;
00350     }
00351 
00359     public function setTimestamp($timestamp)
00360     {
00361         return $this->_timestamp('set', $timestamp);
00362     }
00363 
00371     public function addTimestamp($timestamp)
00372     {
00373         return $this->_timestamp('add', $timestamp);
00374     }
00375 
00383     public function subTimestamp($timestamp)
00384     {
00385         return $this->_timestamp('sub', $timestamp);
00386     }
00387 
00395     public function compareTimestamp($timestamp)
00396     {
00397         return $this->_timestamp('cmp', $timestamp);
00398     }
00399 
00422     public function toString($format = null, $type = null, $locale = null)
00423     {
00424         if (is_object($format)) {
00425             if ($format instanceof Zend_Locale) {
00426                 $locale = $format;
00427                 $format = null;
00428             } else {
00429                 $format = (string) $format;
00430             }
00431         }
00432 
00433         if (is_object($type)) {
00434             if ($type instanceof Zend_Locale) {
00435                 $locale = $type;
00436                 $type   = null;
00437             } else {
00438                 $type = (string) $type;
00439             }
00440         }
00441 
00442         if (($format !== null) && !defined($format)
00443             && ($format != 'ee') && ($format != 'ss') && ($format != 'GG') && ($format != 'MM') && ($format != 'EE') && ($format != 'TT')
00444             && Zend_Locale::isLocale($format, null, false)) {
00445             $locale = $format;
00446             $format = null;
00447         }
00448 
00449         if (($type !== null) and ($type != 'php') and ($type != 'iso') and
00450             Zend_Locale::isLocale($type, null, false)) {
00451             $locale = $type;
00452             $type = null;
00453         }
00454 
00455         if ($locale === null) {
00456             $locale = $this->getLocale();
00457         }
00458 
00459         if ($format === null) {
00460             $format = Zend_Locale_Format::getDateFormat($locale) . ' ' . Zend_Locale_Format::getTimeFormat($locale);
00461         } else if (((self::$_options['format_type'] == 'php') && ($type === null)) or ($type == 'php')) {
00462             $format = Zend_Locale_Format::convertPhpToIsoFormat($format);
00463         }
00464 
00465         return $this->date($this->_toToken($format, $locale), $this->getUnixTimestamp(), false);
00466     }
00467 
00473     public function __toString()
00474     {
00475         return $this->toString(null, $this->_locale);
00476     }
00477 
00485     public function toValue($part = null)
00486     {
00487         $result = $this->get($part);
00488         if (is_numeric($result)) {
00489           return intval("$result");
00490         } else {
00491           return false;
00492         }
00493     }
00494 
00500     public function toArray()
00501     {
00502         return array('day'       => $this->toString(self::DAY_SHORT, 'iso'),
00503                      'month'     => $this->toString(self::MONTH_SHORT, 'iso'),
00504                      'year'      => $this->toString(self::YEAR, 'iso'),
00505                      'hour'      => $this->toString(self::HOUR_SHORT, 'iso'),
00506                      'minute'    => $this->toString(self::MINUTE_SHORT, 'iso'),
00507                      'second'    => $this->toString(self::SECOND_SHORT, 'iso'),
00508                      'timezone'  => $this->toString(self::TIMEZONE, 'iso'),
00509                      'timestamp' => $this->toString(self::TIMESTAMP, 'iso'),
00510                      'weekday'   => $this->toString(self::WEEKDAY_8601, 'iso'),
00511                      'dayofyear' => $this->toString(self::DAY_OF_YEAR, 'iso'),
00512                      'week'      => $this->toString(self::WEEK, 'iso'),
00513                      'gmtsecs'   => $this->toString(self::TIMEZONE_SECS, 'iso'));
00514     }
00515 
00526     public function get($part = null, $locale = null)
00527     {
00528         if ($locale === null) {
00529             $locale = $this->getLocale();
00530         }
00531 
00532         if (($part !== null) && !defined($part)
00533             && ($part != 'ee') && ($part != 'ss') && ($part != 'GG') && ($part != 'MM') && ($part != 'EE') && ($part != 'TT')
00534             && Zend_Locale::isLocale($part, null, false)) {
00535             $locale = $part;
00536             $part = null;
00537         }
00538 
00539         if ($part === null) {
00540             $part = self::TIMESTAMP;
00541         } else if (self::$_options['format_type'] == 'php') {
00542             $part = Zend_Locale_Format::convertPhpToIsoFormat($part);
00543         }
00544 
00545         return $this->date($this->_toToken($part, $locale), $this->getUnixTimestamp(), false);
00546     }
00547 
00555     private function _toToken($part, $locale) {
00556         // get format tokens
00557         $comment = false;
00558         $format  = '';
00559         $orig    = '';
00560         for ($i = 0; $i < strlen($part); ++$i) {
00561             if ($part[$i] == "'") {
00562                 $comment = $comment ? false : true;
00563                 if (isset($part[$i+1]) && ($part[$i+1] == "'")) {
00564                     $comment = $comment ? false : true;
00565                     $format .= "\\'";
00566                     ++$i;
00567                 }
00568 
00569                 $orig = '';
00570                 continue;
00571             }
00572 
00573             if ($comment) {
00574                 $format .= '\\' . $part[$i];
00575                 $orig = '';
00576             } else {
00577                 $orig .= $part[$i];
00578                 if (!isset($part[$i+1]) || (isset($orig[0]) && ($orig[0] != $part[$i+1]))) {
00579                     $format .= $this->_parseIsoToDate($orig, $locale);
00580                     $orig  = '';
00581                 }
00582             }
00583         }
00584 
00585         return $format;
00586     }
00587 
00595     private function _parseIsoToDate($token, $locale) {
00596         switch($token) {
00597             case self::DAY :
00598                 return 'd';
00599                 break;
00600 
00601             case self::WEEKDAY_SHORT :
00602                 $weekday = strtolower($this->date('D', $this->getUnixTimestamp(), false));
00603                 $day     = Zend_Locale_Data::getContent($locale, 'day', array('gregorian', 'format', 'wide', $weekday));
00604                 return $this->_toComment(iconv_substr($day, 0, 3, 'UTF-8'));
00605                 break;
00606 
00607             case self::DAY_SHORT :
00608                 return 'j';
00609                 break;
00610 
00611             case self::WEEKDAY :
00612                 $weekday = strtolower($this->date('D', $this->getUnixTimestamp(), false));
00613                 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'day', array('gregorian', 'format', 'wide', $weekday)));
00614                 break;
00615 
00616             case self::WEEKDAY_8601 :
00617                 return 'N';
00618                 break;
00619 
00620             case 'ee' :
00621                 return $this->_toComment(str_pad($this->date('N', $this->getUnixTimestamp(), false), 2, '0', STR_PAD_LEFT));
00622                 break;
00623 
00624             case self::DAY_SUFFIX :
00625                 return 'S';
00626                 break;
00627 
00628             case self::WEEKDAY_DIGIT :
00629                 return 'w';
00630                 break;
00631 
00632             case self::DAY_OF_YEAR :
00633                 return 'z';
00634                 break;
00635 
00636             case 'DDD' :
00637                 return $this->_toComment(str_pad($this->date('z', $this->getUnixTimestamp(), false), 3, '0', STR_PAD_LEFT));
00638                 break;
00639 
00640             case 'DD' :
00641                 return $this->_toComment(str_pad($this->date('z', $this->getUnixTimestamp(), false), 2, '0', STR_PAD_LEFT));
00642                 break;
00643 
00644             case self::WEEKDAY_NARROW :
00645             case 'EEEEE' :
00646                 $weekday = strtolower($this->date('D', $this->getUnixTimestamp(), false));
00647                 $day = Zend_Locale_Data::getContent($locale, 'day', array('gregorian', 'format', 'abbreviated', $weekday));
00648                 return $this->_toComment(iconv_substr($day, 0, 1, 'UTF-8'));
00649                 break;
00650 
00651             case self::WEEKDAY_NAME :
00652                 $weekday = strtolower($this->date('D', $this->getUnixTimestamp(), false));
00653                 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'day', array('gregorian', 'format', 'abbreviated', $weekday)));
00654                 break;
00655 
00656             case 'w' :
00657                 $week = $this->date('W', $this->getUnixTimestamp(), false);
00658                 return $this->_toComment(($week[0] == '0') ? $week[1] : $week);
00659                 break;
00660 
00661             case self::WEEK :
00662                 return 'W';
00663                 break;
00664 
00665             case self::MONTH_NAME :
00666                 $month = $this->date('n', $this->getUnixTimestamp(), false);
00667                 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'month', array('gregorian', 'format', 'wide', $month)));
00668                 break;
00669 
00670             case self::MONTH :
00671                 return 'm';
00672                 break;
00673 
00674             case self::MONTH_NAME_SHORT :
00675                 $month = $this->date('n', $this->getUnixTimestamp(), false);
00676                 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'month', array('gregorian', 'format', 'abbreviated', $month)));
00677                 break;
00678 
00679             case self::MONTH_SHORT :
00680                 return 'n';
00681                 break;
00682 
00683             case self::MONTH_DAYS :
00684                 return 't';
00685                 break;
00686 
00687             case self::MONTH_NAME_NARROW :
00688                 $month = $this->date('n', $this->getUnixTimestamp(), false);
00689                 $mon = Zend_Locale_Data::getContent($locale, 'month', array('gregorian', 'format', 'abbreviated', $month));
00690                 return $this->_toComment(iconv_substr($mon, 0, 1, 'UTF-8'));
00691                 break;
00692 
00693             case self::LEAPYEAR :
00694                 return 'L';
00695                 break;
00696 
00697             case self::YEAR_8601 :
00698                 return 'o';
00699                 break;
00700 
00701             case self::YEAR :
00702                 return 'Y';
00703                 break;
00704 
00705             case self::YEAR_SHORT :
00706                 return 'y';
00707                 break;
00708 
00709             case self::YEAR_SHORT_8601 :
00710                 return $this->_toComment(substr($this->date('o', $this->getUnixTimestamp(), false), -2, 2));
00711                 break;
00712 
00713             case self::MERIDIEM :
00714                 $am = $this->date('a', $this->getUnixTimestamp(), false);
00715                 if ($am == 'am') {
00716                     return $this->_toComment(Zend_Locale_Data::getContent($locale, 'am'));
00717                 }
00718 
00719                 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'pm'));
00720                 break;
00721 
00722             case self::SWATCH :
00723                 return 'B';
00724                 break;
00725 
00726             case self::HOUR_SHORT_AM :
00727                 return 'g';
00728                 break;
00729 
00730             case self::HOUR_SHORT :
00731                 return 'G';
00732                 break;
00733 
00734             case self::HOUR_AM :
00735                 return 'h';
00736                 break;
00737 
00738             case self::HOUR :
00739                 return 'H';
00740                 break;
00741 
00742             case self::MINUTE :
00743                 return $this->_toComment(str_pad($this->date('i', $this->getUnixTimestamp(), false), 2, '0', STR_PAD_LEFT));
00744                 break;
00745 
00746             case self::SECOND :
00747                 return $this->_toComment(str_pad($this->date('s', $this->getUnixTimestamp(), false), 2, '0', STR_PAD_LEFT));
00748                 break;
00749 
00750             case self::MINUTE_SHORT :
00751                 return 'i';
00752                 break;
00753 
00754             case self::SECOND_SHORT :
00755                 return 's';
00756                 break;
00757 
00758             case self::MILLISECOND :
00759                 return $this->_toComment($this->getMilliSecond());
00760                 break;
00761 
00762             case self::TIMEZONE_NAME :
00763             case 'vvvv' :
00764                 return 'e';
00765                 break;
00766 
00767             case self::DAYLIGHT :
00768                 return 'I';
00769                 break;
00770 
00771             case self::GMT_DIFF :
00772             case 'ZZ' :
00773             case 'ZZZ' :
00774                 return 'O';
00775                 break;
00776 
00777             case self::GMT_DIFF_SEP :
00778                 return 'P';
00779                 break;
00780 
00781             case self::TIMEZONE :
00782             case 'v' :
00783             case 'zz' :
00784             case 'zzz' :
00785                 return 'T';
00786                 break;
00787 
00788             case self::TIMEZONE_SECS :
00789                 return 'Z';
00790                 break;
00791 
00792             case self::ISO_8601 :
00793                 return 'c';
00794                 break;
00795 
00796             case self::RFC_2822 :
00797                 return 'r';
00798                 break;
00799 
00800             case self::TIMESTAMP :
00801                 return 'U';
00802                 break;
00803 
00804             case self::ERA :
00805             case 'GG' :
00806             case 'GGG' :
00807                 $year = $this->date('Y', $this->getUnixTimestamp(), false);
00808                 if ($year < 0) {
00809                     return $this->_toComment(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Abbr', '0')));
00810                 }
00811 
00812                 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Abbr', '1')));
00813                 break;
00814 
00815             case self::ERA_NARROW :
00816                 $year = $this->date('Y', $this->getUnixTimestamp(), false);
00817                 if ($year < 0) {
00818                     return $this->_toComment(iconv_substr(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Abbr', '0')), 0, 1, 'UTF-8')) . '.';
00819                 }
00820 
00821                 return $this->_toComment(iconv_substr(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Abbr', '1')), 0, 1, 'UTF-8')) . '.';
00822                 break;
00823 
00824             case self::ERA_NAME :
00825                 $year = $this->date('Y', $this->getUnixTimestamp(), false);
00826                 if ($year < 0) {
00827                     return $this->_toComment(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Names', '0')));
00828                 }
00829 
00830                 return $this->_toComment(Zend_Locale_Data::getContent($locale, 'era', array('gregorian', 'Names', '1')));
00831                 break;
00832 
00833             case self::DATES :
00834                 return $this->_toToken(Zend_Locale_Format::getDateFormat($locale), $locale);
00835                 break;
00836 
00837             case self::DATE_FULL :
00838                 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'full')), $locale);
00839                 break;
00840 
00841             case self::DATE_LONG :
00842                 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'long')), $locale);
00843                 break;
00844 
00845             case self::DATE_MEDIUM :
00846                 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'medium')), $locale);
00847                 break;
00848 
00849             case self::DATE_SHORT :
00850                 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'short')), $locale);
00851                 break;
00852 
00853             case self::TIMES :
00854                 return $this->_toToken(Zend_Locale_Format::getTimeFormat($locale), $locale);
00855                 break;
00856 
00857             case self::TIME_FULL :
00858                 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'time', 'full'), $locale);
00859                 break;
00860 
00861             case self::TIME_LONG :
00862                 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'time', 'long'), $locale);
00863                 break;
00864 
00865             case self::TIME_MEDIUM :
00866                 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'time', 'medium'), $locale);
00867                 break;
00868 
00869             case self::TIME_SHORT :
00870                 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'time', 'short'), $locale);
00871                 break;
00872 
00873             case self::DATETIME :
00874                 return $this->_toToken(Zend_Locale_Format::getDateTimeFormat($locale), $locale);
00875                 break;
00876 
00877             case self::DATETIME_FULL :
00878                 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'full')), $locale);
00879                 break;
00880 
00881             case self::DATETIME_LONG :
00882                 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'long')), $locale);
00883                 break;
00884 
00885             case self::DATETIME_MEDIUM :
00886                 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'medium')), $locale);
00887                 break;
00888 
00889             case self::DATETIME_SHORT :
00890                 return $this->_toToken(Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'short')), $locale);
00891                 break;
00892 
00893             case self::ATOM :
00894                 return 'Y\-m\-d\TH\:i\:sP';
00895                 break;
00896 
00897             case self::COOKIE :
00898                 return 'l\, d\-M\-y H\:i\:s e';
00899                 break;
00900 
00901             case self::RFC_822 :
00902                 return 'D\, d M y H\:i\:s O';
00903                 break;
00904 
00905             case self::RFC_850 :
00906                 return 'l\, d\-M\-y H\:i\:s e';
00907                 break;
00908 
00909             case self::RFC_1036 :
00910                 return 'D\, d M y H\:i\:s O';
00911                 break;
00912 
00913             case self::RFC_1123 :
00914                 return 'D\, d M Y H\:i\:s O';
00915                 break;
00916 
00917             case self::RFC_3339 :
00918                 return 'Y\-m\-d\TH\:i\:sP';
00919                 break;
00920 
00921             case self::RSS :
00922                 return 'D\, d M Y H\:i\:s O';
00923                 break;
00924 
00925             case self::W3C :
00926                 return 'Y\-m\-d\TH\:i\:sP';
00927                 break;
00928         }
00929 
00930         if ($token == '') {
00931             return '';
00932         }
00933 
00934         switch ($token[0]) {
00935             case 'y' :
00936                 if ((strlen($token) == 4) && (abs($this->getUnixTimestamp()) <= 0x7FFFFFFF)) {
00937                     return 'Y';
00938                 }
00939 
00940                 $length = iconv_strlen($token, 'UTF-8');
00941                 return $this->_toComment(str_pad($this->date('Y', $this->getUnixTimestamp(), false), $length, '0', STR_PAD_LEFT));
00942                 break;
00943 
00944             case 'Y' :
00945                 if ((strlen($token) == 4) && (abs($this->getUnixTimestamp()) <= 0x7FFFFFFF)) {
00946                     return 'o';
00947                 }
00948 
00949                 $length = iconv_strlen($token, 'UTF-8');
00950                 return $this->_toComment(str_pad($this->date('o', $this->getUnixTimestamp(), false), $length, '0', STR_PAD_LEFT));
00951                 break;
00952 
00953             case 'A' :
00954                 $length  = iconv_strlen($token, 'UTF-8');
00955                 $result  = substr($this->getMilliSecond(), 0, 3);
00956                 $result += $this->date('s', $this->getUnixTimestamp(), false) * 1000;
00957                 $result += $this->date('i', $this->getUnixTimestamp(), false) * 60000;
00958                 $result += $this->date('H', $this->getUnixTimestamp(), false) * 3600000;
00959 
00960                 return $this->_toComment(str_pad($result, $length, '0', STR_PAD_LEFT));
00961                 break;
00962         }
00963 
00964         return $this->_toComment($token);
00965     }
00966 
00973     private function _toComment($token)
00974     {
00975         $token = str_split($token);
00976         $result = '';
00977         foreach ($token as $tok) {
00978             $result .= '\\' . $tok;
00979         }
00980 
00981         return $result;
00982     }
00983 
00992     private function _getDigitFromName($name)
00993     {
00994         switch($name) {
00995             case "Jan":
00996                 return 1;
00997 
00998             case "Feb":
00999                 return 2;
01000 
01001             case "Mar":
01002                 return 3;
01003 
01004             case "Apr":
01005                 return 4;
01006 
01007             case "May":
01008                 return 5;
01009 
01010             case "Jun":
01011                 return 6;
01012 
01013             case "Jul":
01014                 return 7;
01015 
01016             case "Aug":
01017                 return 8;
01018 
01019             case "Sep":
01020                 return 9;
01021 
01022             case "Oct":
01023                 return 10;
01024 
01025             case "Nov":
01026                 return 11;
01027 
01028             case "Dec":
01029                 return 12;
01030 
01031             default:
01032                 require_once 'Zend/Date/Exception.php';
01033                 throw new Zend_Date_Exception('Month ($name) is not a known month');
01034         }
01035     }
01036 
01044     public static function getFullYear($value)
01045     {
01046         if ($value >= 0) {
01047             if ($value < 70) {
01048                 $value += 2000;
01049             } else if ($value < 100) {
01050                 $value += 1900;
01051             }
01052         }
01053         return $value;
01054     }
01055 
01068     public function set($date, $part = null, $locale = null)
01069     {
01070         if (self::$_options['format_type'] == 'php') {
01071             $part = Zend_Locale_Format::convertPhpToIsoFormat($part);
01072         }
01073 
01074         $zone = $this->getTimezoneFromString($date);
01075         $this->setTimezone($zone);
01076 
01077         $this->_calculate('set', $date, $part, $locale);
01078         return $this;
01079     }
01080 
01096     public function add($date, $part = self::TIMESTAMP, $locale = null)
01097     {
01098         if (self::$_options['format_type'] == 'php') {
01099             $part = Zend_Locale_Format::convertPhpToIsoFormat($part);
01100         }
01101 
01102         $this->_calculate('add', $date, $part, $locale);
01103         return $this;
01104     }
01105 
01119     public function sub($date, $part = self::TIMESTAMP, $locale = null)
01120     {
01121         if (self::$_options['format_type'] == 'php') {
01122             $part = Zend_Locale_Format::convertPhpToIsoFormat($part);
01123         }
01124 
01125         $this->_calculate('sub', $date, $part, $locale);
01126         return $this;
01127     }
01128 
01139     public function compare($date, $part = self::TIMESTAMP, $locale = null)
01140     {
01141         if (self::$_options['format_type'] == 'php') {
01142             $part = Zend_Locale_Format::convertPhpToIsoFormat($part);
01143         }
01144 
01145         $compare = $this->_calculate('cmp', $date, $part, $locale);
01146 
01147         if ($compare > 0) {
01148             return 1;
01149         } else if ($compare < 0) {
01150             return -1;
01151         }
01152         return 0;
01153     }
01154 
01169     public function copyPart($part, $locale = null)
01170     {
01171         $clone = clone $this;           // copy all instance variables
01172         $clone->setUnixTimestamp(0);    // except the timestamp
01173         if ($locale != null) {
01174             $clone->setLocale($locale); // set an other locale if selected
01175         }
01176         $clone->set($this, $part);
01177         return $clone;
01178     }
01179 
01186     public function getTimezoneFromString($zone)
01187     {
01188         if (is_array($zone)) {
01189             return $this->getTimezone();
01190         }
01191 
01192         if ($zone instanceof Zend_Date) {
01193             return $zone->getTimezone();
01194         }
01195 
01196         $match = array();
01197         preg_match('/\dZ$/', $zone, $match);
01198         if (!empty($match)) {
01199             return "Etc/UTC";
01200         }
01201 
01202         preg_match('/([+-]\d{2}):{0,1}\d{2}/', $zone, $match);
01203         if (!empty($match) and ($match[count($match) - 1] <= 12) and ($match[count($match) - 1] >= -12)) {
01204             $zone = "Etc/GMT";
01205             $zone .= ($match[count($match) - 1] < 0) ? "+" : "-";
01206             $zone .= (int) abs($match[count($match) - 1]);
01207             return $zone;
01208         }
01209 
01210         preg_match('/([[:alpha:]\/]{3,30})(?!.*([[:alpha:]\/]{3,30}))/', $zone, $match);
01211         try {
01212             if (!empty($match) and (!is_int($match[count($match) - 1]))) {
01213                 $oldzone = $this->getTimezone();
01214                 $this->setTimezone($match[count($match) - 1]);
01215                 $result = $this->getTimezone();
01216                 $this->setTimezone($oldzone);
01217                 if ($result !== $oldzone) {
01218                     return $match[count($match) - 1];
01219                 }
01220             }
01221         } catch (Exception $e) {
01222             // fall through
01223         }
01224 
01225         return $this->getTimezone();
01226     }
01227 
01237     private function _assign($calc, $date, $comp = 0, $dst = false)
01238     {
01239         switch ($calc) {
01240             case 'set' :
01241                 if (!empty($comp)) {
01242                     $this->setUnixTimestamp(call_user_func(Zend_Locale_Math::$sub, $this->getUnixTimestamp(), $comp));
01243                 }
01244                 $this->setUnixTimestamp(call_user_func(Zend_Locale_Math::$add, $this->getUnixTimestamp(), $date));
01245                 $value = $this->getUnixTimestamp();
01246                 break;
01247             case 'add' :
01248                 $this->setUnixTimestamp(call_user_func(Zend_Locale_Math::$add, $this->getUnixTimestamp(), $date));
01249                 $value = $this->getUnixTimestamp();
01250                 break;
01251             case 'sub' :
01252                 $this->setUnixTimestamp(call_user_func(Zend_Locale_Math::$sub, $this->getUnixTimestamp(), $date));
01253                 $value = $this->getUnixTimestamp();
01254                 break;
01255             default :
01256                 // cmp - compare
01257                 return call_user_func(Zend_Locale_Math::$comp, $comp, $date);
01258                 break;
01259         }
01260 
01261         // dst-correction if 'fix_dst' = true and dst !== false but only for non UTC and non GMT
01262         if ((self::$_options['fix_dst'] === true) and ($dst !== false) and ($this->_dst === true)) {
01263             $hour = $this->toString(self::HOUR, 'iso');
01264             if ($hour != $dst) {
01265                 if (($dst == ($hour + 1)) or ($dst == ($hour - 23))) {
01266                     $value += 3600;
01267                 } else if (($dst == ($hour - 1)) or ($dst == ($hour + 23))) {
01268                     $value -= 3600;
01269                 }
01270                 $this->setUnixTimestamp($value);
01271             }
01272         }
01273         return $this->getUnixTimestamp();
01274     }
01275 
01276 
01287     private function _calculate($calc, $date, $part, $locale)
01288     {
01289         if ($date === null) {
01290             require_once 'Zend/Date/Exception.php';
01291             throw new Zend_Date_Exception('parameter $date must be set, null is not allowed');
01292         }
01293 
01294         if (($part !== null) && (strlen($part) !== 2) && (Zend_Locale::isLocale($part, null, false))) {
01295             $locale = $part;
01296             $part   = null;
01297         }
01298 
01299         if ($locale === null) {
01300             $locale = $this->getLocale();
01301         }
01302 
01303         $locale = (string) $locale;
01304 
01305         // Create date parts
01306         $year   = $this->toString(self::YEAR, 'iso');
01307         $month  = $this->toString(self::MONTH_SHORT, 'iso');
01308         $day    = $this->toString(self::DAY_SHORT, 'iso');
01309         $hour   = $this->toString(self::HOUR_SHORT, 'iso');
01310         $minute = $this->toString(self::MINUTE_SHORT, 'iso');
01311         $second = $this->toString(self::SECOND_SHORT, 'iso');
01312         // If object extract value
01313         if ($date instanceof Zend_Date) {
01314             $date = $date->toString($part, 'iso', $locale);
01315         }
01316 
01317         if (is_array($date) === true) {
01318             if (empty($part) === false) {
01319                 switch($part) {
01320                     // Fall through
01321                     case self::DAY:
01322                     case self::DAY_SHORT:
01323                         if (isset($date['day']) === true) {
01324                             $date = $date['day'];
01325                         }
01326                         break;
01327                     // Fall through
01328                     case self::WEEKDAY_SHORT:
01329                     case self::WEEKDAY:
01330                     case self::WEEKDAY_8601:
01331                     case self::WEEKDAY_DIGIT:
01332                     case self::WEEKDAY_NARROW:
01333                     case self::WEEKDAY_NAME:
01334                         if (isset($date['weekday']) === true) {
01335                             $date = $date['weekday'];
01336                             $part = self::WEEKDAY_DIGIT;
01337                         }
01338                         break;
01339                     case self::DAY_OF_YEAR:
01340                         if (isset($date['day_of_year']) === true) {
01341                             $date = $date['day_of_year'];
01342                         }
01343                         break;
01344                     // Fall through
01345                     case self::MONTH:
01346                     case self::MONTH_SHORT:
01347                     case self::MONTH_NAME:
01348                     case self::MONTH_NAME_SHORT:
01349                     case self::MONTH_NAME_NARROW:
01350                         if (isset($date['month']) === true) {
01351                             $date = $date['month'];
01352                         }
01353                         break;
01354                     // Fall through
01355                     case self::YEAR:
01356                     case self::YEAR_SHORT:
01357                     case self::YEAR_8601:
01358                     case self::YEAR_SHORT_8601:
01359                         if (isset($date['year']) === true) {
01360                             $date = $date['year'];
01361                         }
01362                         break;
01363                     // Fall through
01364                     case self::HOUR:
01365                     case self::HOUR_AM:
01366                     case self::HOUR_SHORT:
01367                     case self::HOUR_SHORT_AM:
01368                         if (isset($date['hour']) === true) {
01369                             $date = $date['hour'];
01370                         }
01371                         break;
01372                     // Fall through
01373                     case self::MINUTE:
01374                     case self::MINUTE_SHORT:
01375                         if (isset($date['minute']) === true) {
01376                             $date = $date['minute'];
01377                         }
01378                         break;
01379                     // Fall through
01380                     case self::SECOND:
01381                     case self::SECOND_SHORT:
01382                         if (isset($date['second']) === true) {
01383                             $date = $date['second'];
01384                         }
01385                         break;
01386                     // Fall through
01387                     case self::TIMEZONE:
01388                     case self::TIMEZONE_NAME:
01389                         if (isset($date['timezone']) === true) {
01390                             $date = $date['timezone'];
01391                         }
01392                         break;
01393                     case self::TIMESTAMP:
01394                         if (isset($date['timestamp']) === true) {
01395                             $date = $date['timestamp'];
01396                         }
01397                         break;
01398                     case self::WEEK:
01399                         if (isset($date['week']) === true) {
01400                             $date = $date['week'];
01401                         }
01402                         break;
01403                     case self::TIMEZONE_SECS:
01404                         if (isset($date['gmtsecs']) === true) {
01405                             $date = $date['gmtsecs'];
01406                         }
01407                         break;
01408                     default:
01409                         require_once 'Zend/Date/Exception.php';
01410                         throw new Zend_Date_Exception("datepart for part ($part) not found in array");
01411                         break;
01412                 }
01413             } else {
01414                 $hours = 0;
01415                 if (isset($date['hour']) === true) {
01416                     $hours = $date['hour'];
01417                 }
01418                 $minutes = 0;
01419                 if (isset($date['minute']) === true) {
01420                     $minutes = $date['minute'];
01421                 }
01422                 $seconds = 0;
01423                 if (isset($date['second']) === true) {
01424                     $seconds = $date['second'];
01425                 }
01426                 $months = 0;
01427                 if (isset($date['month']) === true) {
01428                     $months = $date['month'];
01429                 }
01430                 $days = 0;
01431                 if (isset($date['day']) === true) {
01432                     $days = $date['day'];
01433                 }
01434                 $years = 0;
01435                 if (isset($date['year']) === true) {
01436                     $years = $date['year'];
01437                 }
01438                 return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, $months, $days, $years, true),
01439                                              $this->mktime($hour, $minute, $second, $month, $day, $year, true), $hour);
01440             }
01441         }
01442 
01443         // $date as object, part of foreign date as own date
01444         switch($part) {
01445 
01446             // day formats
01447             case self::DAY:
01448                 if (is_numeric($date)) {
01449                     return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true),
01450                                                  $this->mktime(0, 0, 0, 1, 1 + intval($day), 1970, true), $hour);
01451                 }
01452 
01453                 require_once 'Zend/Date/Exception.php';
01454                 throw new Zend_Date_Exception("invalid date ($date) operand, day expected", 0, null, $date);
01455                 break;
01456 
01457             case self::WEEKDAY_SHORT:
01458                 $daylist = Zend_Locale_Data::getList($locale, 'day');
01459                 $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale);
01460                 $cnt = 0;
01461 
01462                 foreach ($daylist as $key => $value) {
01463                     if (strtoupper(iconv_substr($value, 0, 3, 'UTF-8')) == strtoupper($date)) {
01464                          $found = $cnt;
01465                         break;
01466                     }
01467                     ++$cnt;
01468                 }
01469 
01470                 // Weekday found
01471                 if ($cnt < 7) {
01472                     return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true),
01473                                                  $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour);
01474                 }
01475 
01476                 // Weekday not found
01477                 require_once 'Zend/Date/Exception.php';
01478                 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date);
01479                 break;
01480 
01481             case self::DAY_SHORT:
01482                 if (is_numeric($date)) {
01483                     return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true),
01484                                                  $this->mktime(0, 0, 0, 1, 1 + intval($day), 1970, true), $hour);
01485                 }
01486 
01487                 require_once 'Zend/Date/Exception.php';
01488                 throw new Zend_Date_Exception("invalid date ($date) operand, day expected", 0, null, $date);
01489                 break;
01490 
01491             case self::WEEKDAY:
01492                 $daylist = Zend_Locale_Data::getList($locale, 'day');
01493                 $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale);
01494                 $cnt = 0;
01495 
01496                 foreach ($daylist as $key => $value) {
01497                     if (strtoupper($value) == strtoupper($date)) {
01498                         $found = $cnt;
01499                         break;
01500                     }
01501                     ++$cnt;
01502                 }
01503 
01504                 // Weekday found
01505                 if ($cnt < 7) {
01506                     return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true),
01507                                                  $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour);
01508                 }
01509 
01510                 // Weekday not found
01511                 require_once 'Zend/Date/Exception.php';
01512                 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date);
01513                 break;
01514 
01515             case self::WEEKDAY_8601:
01516                 $weekday = (int) $this->toString(self::WEEKDAY_8601, 'iso', $locale);
01517                 if ((intval($date) > 0) and (intval($date) < 8)) {
01518                     return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + intval($date), 1970, true),
01519                                                  $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour);
01520                 }
01521 
01522                 // Weekday not found
01523                 require_once 'Zend/Date/Exception.php';
01524                 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date);
01525                 break;
01526 
01527             case self::DAY_SUFFIX:
01528                 require_once 'Zend/Date/Exception.php';
01529                 throw new Zend_Date_Exception('day suffix not supported', 0, null, $date);
01530                 break;
01531 
01532             case self::WEEKDAY_DIGIT:
01533                 $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale);
01534                 if (is_numeric($date) and (intval($date) >= 0) and (intval($date) < 7)) {
01535                     return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $date, 1970, true),
01536                                                  $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour);
01537                 }
01538 
01539                 // Weekday not found
01540                 require_once 'Zend/Date/Exception.php';
01541                 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date);
01542                 break;
01543 
01544             case self::DAY_OF_YEAR:
01545                 if (is_numeric($date)) {
01546                     if (($calc == 'add') || ($calc == 'sub')) {
01547                         $year = 1970;
01548                         ++$date;
01549                         ++$day;
01550                     }
01551 
01552                     return $this->_assign($calc, $this->mktime(0, 0, 0, 1, $date, $year, true),
01553                                                  $this->mktime(0, 0, 0, $month, $day, $year, true), $hour);
01554                 }
01555 
01556                 require_once 'Zend/Date/Exception.php';
01557                 throw new Zend_Date_Exception("invalid date ($date) operand, day expected", 0, null, $date);
01558                 break;
01559 
01560             case self::WEEKDAY_NARROW:
01561                 $daylist = Zend_Locale_Data::getList($locale, 'day', array('gregorian', 'format', 'abbreviated'));
01562                 $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale);
01563                 $cnt = 0;
01564                 foreach ($daylist as $key => $value) {
01565                     if (strtoupper(iconv_substr($value, 0, 1, 'UTF-8')) == strtoupper($date)) {
01566                         $found = $cnt;
01567                         break;
01568                     }
01569                     ++$cnt;
01570                 }
01571 
01572                 // Weekday found
01573                 if ($cnt < 7) {
01574                     return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true),
01575                                                  $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour);
01576                 }
01577 
01578                 // Weekday not found
01579                 require_once 'Zend/Date/Exception.php';
01580                 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date);
01581                 break;
01582 
01583             case self::WEEKDAY_NAME:
01584                 $daylist = Zend_Locale_Data::getList($locale, 'day', array('gregorian', 'format', 'abbreviated'));
01585                 $weekday = (int) $this->toString(self::WEEKDAY_DIGIT, 'iso', $locale);
01586                 $cnt = 0;
01587                 foreach ($daylist as $key => $value) {
01588                     if (strtoupper($value) == strtoupper($date)) {
01589                         $found = $cnt;
01590                         break;
01591                     }
01592                     ++$cnt;
01593                 }
01594 
01595                 // Weekday found
01596                 if ($cnt < 7) {
01597                     return $this->_assign($calc, $this->mktime(0, 0, 0, 1, 1 + $found, 1970, true),
01598                                                  $this->mktime(0, 0, 0, 1, 1 + $weekday, 1970, true), $hour);
01599                 }
01600 
01601                 // Weekday not found
01602                 require_once 'Zend/Date/Exception.php';
01603                 throw new Zend_Date_Exception("invalid date ($date) operand, weekday expected", 0, null, $date);
01604                 break;
01605 
01606             // week formats
01607             case self::WEEK:
01608                 if (is_numeric($date)) {
01609                     $week = (int) $this->toString(self::WEEK, 'iso', $locale);
01610                     return $this->_assign($calc, parent::mktime(0, 0, 0, 1, 1 + ($date * 7), 1970, true),
01611                                                  parent::mktime(0, 0, 0, 1, 1 + ($week * 7), 1970, true), $hour);
01612                 }
01613 
01614                 require_once 'Zend/Date/Exception.php';
01615                 throw new Zend_Date_Exception("invalid date ($date) operand, week expected", 0, null, $date);
01616                 break;
01617 
01618             // month formats
01619             case self::MONTH_NAME:
01620                 $monthlist = Zend_Locale_Data::getList($locale, 'month');
01621                 $cnt = 0;
01622                 foreach ($monthlist as $key => $value) {
01623                     if (strtoupper($value) == strtoupper($date)) {
01624                         $found = $key;
01625                         break;
01626                     }
01627                     ++$cnt;
01628                 }
01629                 $date = array_search($date, $monthlist);
01630 
01631                 // Monthname found
01632                 if ($cnt < 12) {
01633                     $fixday = 0;
01634                     if ($calc == 'add') {
01635                         $date += $found;
01636                         $calc = 'set';
01637                         if (self::$_options['extend_month'] == false) {
01638                             $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false));
01639                             if ($parts['mday'] != $day) {
01640                                 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day);
01641                             }
01642                         }
01643                     } else if ($calc == 'sub') {
01644                         $date = $month - $found;
01645                         $calc = 'set';
01646                         if (self::$_options['extend_month'] == false) {
01647                             $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false));
01648                             if ($parts['mday'] != $day) {
01649                                 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day);
01650                             }
01651                         }
01652                     }
01653                     return $this->_assign($calc, $this->mktime(0, 0, 0, $date,  $day + $fixday, $year, true),
01654                                                  $this->mktime(0, 0, 0, $month, $day, $year, true), $hour);
01655                 }
01656 
01657                 // Monthname not found
01658                 require_once 'Zend/Date/Exception.php';
01659                 throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date);
01660                 break;
01661 
01662             case self::MONTH:
01663                 if (is_numeric($date)) {
01664                     $fixday = 0;
01665                     if ($calc == 'add') {
01666                         $date += $month;
01667                         $calc = 'set';
01668                         if (self::$_options['extend_month'] == false) {
01669                             $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false));
01670                             if ($parts['mday'] != $day) {
01671                                 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day);
01672                             }
01673                         }
01674                     } else if ($calc == 'sub') {
01675                         $date = $month - $date;
01676                         $calc = 'set';
01677                         if (self::$_options['extend_month'] == false) {
01678                             $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false));
01679                             if ($parts['mday'] != $day) {
01680                                 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day);
01681                             }
01682                         }
01683                     }
01684                     return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true),
01685                                                  $this->mktime(0, 0, 0, $month, $day, $year, true), $hour);
01686                 }
01687 
01688                 require_once 'Zend/Date/Exception.php';
01689                 throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date);
01690                 break;
01691 
01692             case self::MONTH_NAME_SHORT:
01693                 $monthlist = Zend_Locale_Data::getList($locale, 'month', array('gregorian', 'format', 'abbreviated'));
01694                 $cnt = 0;
01695                 foreach ($monthlist as $key => $value) {
01696                     if (strtoupper($value) == strtoupper($date)) {
01697                         $found = $key;
01698                         break;
01699                     }
01700                     ++$cnt;
01701                 }
01702                 $date = array_search($date, $monthlist);
01703 
01704                 // Monthname found
01705                 if ($cnt < 12) {
01706                     $fixday = 0;
01707                     if ($calc == 'add') {
01708                         $date += $found;
01709                         $calc = 'set';
01710                         if (self::$_options['extend_month'] === false) {
01711                             $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false));
01712                             if ($parts['mday'] != $day) {
01713                                 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day);
01714                             }
01715                         }
01716                     } else if ($calc == 'sub') {
01717                         $date = $month - $found;
01718                         $calc = 'set';
01719                         if (self::$_options['extend_month'] === false) {
01720                             $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false));
01721                             if ($parts['mday'] != $day) {
01722                                 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day);
01723                             }
01724                         }
01725                     }
01726                     return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true),
01727                                                  $this->mktime(0, 0, 0, $month, $day, $year, true), $hour);
01728                 }
01729 
01730                 // Monthname not found
01731                 require_once 'Zend/Date/Exception.php';
01732                 throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date);
01733                 break;
01734 
01735             case self::MONTH_SHORT:
01736                 if (is_numeric($date) === true) {
01737                     $fixday = 0;
01738                     if ($calc === 'add') {
01739                         $date += $month;
01740                         $calc  = 'set';
01741                         if (self::$_options['extend_month'] === false) {
01742                             $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false));
01743                             if ($parts['mday'] != $day) {
01744                                 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day);
01745                             }
01746                         }
01747                     } else if ($calc === 'sub') {
01748                         $date = $month - $date;
01749                         $calc = 'set';
01750                         if (self::$_options['extend_month'] === false) {
01751                             $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false));
01752                             if ($parts['mday'] != $day) {
01753                                 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day);
01754                             }
01755                         }
01756                     }
01757 
01758                     return $this->_assign($calc, $this->mktime(0, 0, 0, $date,  $day + $fixday, $year, true),
01759                                                  $this->mktime(0, 0, 0, $month, $day,           $year, true), $hour);
01760                 }
01761 
01762                 require_once 'Zend/Date/Exception.php';
01763                 throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date);
01764                 break;
01765 
01766             case self::MONTH_DAYS:
01767                 require_once 'Zend/Date/Exception.php';
01768                 throw new Zend_Date_Exception('month days not supported', 0, null, $date);
01769                 break;
01770 
01771             case self::MONTH_NAME_NARROW:
01772                 $monthlist = Zend_Locale_Data::getList($locale, 'month', array('gregorian', 'stand-alone', 'narrow'));
01773                 $cnt       = 0;
01774                 foreach ($monthlist as $key => $value) {
01775                     if (strtoupper($value) === strtoupper($date)) {
01776                         $found = $key;
01777                         break;
01778                     }
01779                     ++$cnt;
01780                 }
01781                 $date = array_search($date, $monthlist);
01782 
01783                 // Monthname found
01784                 if ($cnt < 12) {
01785                     $fixday = 0;
01786                     if ($calc === 'add') {
01787                         $date += $found;
01788                         $calc  = 'set';
01789                         if (self::$_options['extend_month'] === false) {
01790                             $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false));
01791                             if ($parts['mday'] != $day) {
01792                                 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day);
01793                             }
01794                         }
01795                     } else if ($calc === 'sub') {
01796                         $date = $month - $found;
01797                         $calc = 'set';
01798                         if (self::$_options['extend_month'] === false) {
01799                             $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false));
01800                             if ($parts['mday'] != $day) {
01801                                 $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day);
01802                             }
01803                         }
01804                     }
01805                     return $this->_assign($calc, $this->mktime(0, 0, 0, $date,  $day + $fixday, $year, true),
01806                                                  $this->mktime(0, 0, 0, $month, $day,           $year, true), $hour);
01807                 }
01808 
01809                 // Monthname not found
01810                 require_once 'Zend/Date/Exception.php';
01811                 throw new Zend_Date_Exception("invalid date ($date) operand, month expected", 0, null, $date);
01812                 break;
01813 
01814             // year formats
01815             case self::LEAPYEAR:
01816                 require_once 'Zend/Date/Exception.php';
01817                 throw new Zend_Date_Exception('leap year not supported', 0, null, $date);
01818                 break;
01819 
01820             case self::YEAR_8601:
01821                 if (is_numeric($date)) {
01822                     if ($calc === 'add') {
01823                         $date += $year;
01824                         $calc  = 'set';
01825                     } else if ($calc === 'sub') {
01826                         $date = $year - $date;
01827                         $calc = 'set';
01828                     }
01829 
01830                     return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, intval($date), true),
01831                                                  $this->mktime(0, 0, 0, $month, $day, $year,         true), false);
01832                 }
01833 
01834                 require_once 'Zend/Date/Exception.php';
01835                 throw new Zend_Date_Exception("invalid date ($date) operand, year expected", 0, null, $date);
01836                 break;
01837 
01838             case self::YEAR:
01839                 if (is_numeric($date)) {
01840                     if ($calc === 'add') {
01841                         $date += $year;
01842                         $calc  = 'set';
01843                     } else if ($calc === 'sub') {
01844                         $date = $year - $date;
01845                         $calc = 'set';
01846                     }
01847 
01848                     return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, intval($date), true),
01849                                                  $this->mktime(0, 0, 0, $month, $day, $year,         true), false);
01850                 }
01851 
01852                 require_once 'Zend/Date/Exception.php';
01853                 throw new Zend_Date_Exception("invalid date ($date) operand, year expected", 0, null, $date);
01854                 break;
01855 
01856             case self::YEAR_SHORT:
01857                 if (is_numeric($date)) {
01858                     $date = intval($date);
01859                     if (($calc == 'set') || ($calc == 'cmp')) {
01860                         $date = self::getFullYear($date);
01861                     }
01862                     if ($calc === 'add') {
01863                         $date += $year;
01864                         $calc  = 'set';
01865                     } else if ($calc === 'sub') {
01866                         $date = $year - $date;
01867                         $calc = 'set';
01868                     }
01869 
01870                     return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, $date, true),
01871                                                  $this->mktime(0, 0, 0, $month, $day, $year, true), false);
01872                 }
01873 
01874                 require_once 'Zend/Date/Exception.php';
01875                 throw new Zend_Date_Exception("invalid date ($date) operand, year expected", 0, null, $date);
01876                 break;
01877 
01878             case self::YEAR_SHORT_8601:
01879                 if (is_numeric($date)) {
01880                     $date = intval($date);
01881                     if (($calc === 'set') || ($calc === 'cmp')) {
01882                         $date = self::getFullYear($date);
01883                     }
01884                     if ($calc === 'add') {
01885                         $date += $year;
01886                         $calc  = 'set';
01887                     } else if ($calc === 'sub') {
01888                         $date = $year - $date;
01889                         $calc = 'set';
01890                     }
01891 
01892                     return $this->_assign($calc, $this->mktime(0, 0, 0, $month, $day, $date, true),
01893                                                  $this->mktime(0, 0, 0, $month, $day, $year, true), false);
01894                 }
01895 
01896                 require_once 'Zend/Date/Exception.php';
01897                 throw new Zend_Date_Exception("invalid date ($date) operand, year expected", 0, null, $date);
01898                 break;
01899 
01900             // time formats
01901             case self::MERIDIEM:
01902                 require_once 'Zend/Date/Exception.php';
01903                 throw new Zend_Date_Exception('meridiem not supported', 0, null, $date);
01904                 break;
01905 
01906             case self::SWATCH:
01907                 if (is_numeric($date)) {
01908                     $rest    = intval($date);
01909                     $hours   = floor($rest * 24 / 1000);
01910                     $rest    = $rest - ($hours * 1000 / 24);
01911                     $minutes = floor($rest * 1440 / 1000);
01912                     $rest    = $rest - ($minutes * 1000 / 1440);
01913                     $seconds = floor($rest * 86400 / 1000);
01914                     return $this->_assign($calc, $this->mktime($hours, $minutes, $seconds, 1, 1, 1970, true),
01915                                                  $this->mktime($hour,  $minute,  $second,  1, 1, 1970, true), false);
01916                 }
01917 
01918                 require_once 'Zend/Date/Exception.php';
01919                 throw new Zend_Date_Exception("invalid date ($date) operand, swatchstamp expected", 0, null, $date);
01920                 break;
01921 
01922             case self::HOUR_SHORT_AM:
01923                 if (is_numeric($date)) {
01924                     return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true),
01925                                                  $this->mktime($hour,         0, 0, 1, 1, 1970, true), false);
01926                 }
01927 
01928                 require_once 'Zend/Date/Exception.php';
01929                 throw new Zend_Date_Exception("invalid date ($date) operand, hour expected", 0, null, $date);
01930                 break;
01931 
01932             case self::HOUR_SHORT:
01933                 if (is_numeric($date)) {
01934                     return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true),
01935                                                  $this->mktime($hour,         0, 0, 1, 1, 1970, true), false);
01936                 }
01937 
01938                 require_once 'Zend/Date/Exception.php';
01939                 throw new Zend_Date_Exception("invalid date ($date) operand, hour expected", 0, null, $date);
01940                 break;
01941 
01942             case self::HOUR_AM:
01943                 if (is_numeric($date)) {
01944                     return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true),
01945                                                  $this->mktime($hour,         0, 0, 1, 1, 1970, true), false);
01946                 }
01947 
01948                 require_once 'Zend/Date/Exception.php';
01949                 throw new Zend_Date_Exception("invalid date ($date) operand, hour expected", 0, null, $date);
01950                 break;
01951 
01952             case self::HOUR:
01953                 if (is_numeric($date)) {
01954                     return $this->_assign($calc, $this->mktime(intval($date), 0, 0, 1, 1, 1970, true),
01955                                                  $this->mktime($hour,         0, 0, 1, 1, 1970, true), false);
01956                 }
01957 
01958                 require_once 'Zend/Date/Exception.php';
01959                 throw new Zend_Date_Exception("invalid date ($date) operand, hour expected", 0, null, $date);
01960                 break;
01961 
01962             case self::MINUTE:
01963                 if (is_numeric($date)) {
01964                     return $this->_assign($calc, $this->mktime(0, intval($date), 0, 1, 1, 1970, true),
01965                                                  $this->mktime(0, $minute,       0, 1, 1, 1970, true), false);
01966                 }
01967 
01968                 require_once 'Zend/Date/Exception.php';
01969                 throw new Zend_Date_Exception("invalid date ($date) operand, minute expected", 0, null, $date);
01970                 break;
01971 
01972             case self::SECOND:
01973                 if (is_numeric($date)) {
01974                     return $this->_assign($calc, $this->mktime(0, 0, intval($date), 1, 1, 1970, true),
01975                                                  $this->mktime(0, 0, $second,       1, 1, 1970, true), false);
01976                 }
01977 
01978                 require_once 'Zend/Date/Exception.php';
01979                 throw new Zend_Date_Exception("invalid date ($date) operand, second expected", 0, null, $date);
01980                 break;
01981 
01982             case self::MILLISECOND:
01983                 if (is_numeric($date)) {
01984                     switch($calc) {
01985                         case 'set' :
01986                             return $this->setMillisecond($date);
01987                             break;
01988                         case 'add' :
01989                             return $this->addMillisecond($date);
01990                             break;
01991                         case 'sub' :
01992                             return $this->subMillisecond($date);
01993                             break;
01994                     }
01995 
01996                     return $this->compareMillisecond($date);
01997                 }
01998 
01999                 require_once 'Zend/Date/Exception.php';
02000                 throw new Zend_Date_Exception("invalid date ($date) operand, milliseconds expected", 0, null, $date);
02001                 break;
02002 
02003             case self::MINUTE_SHORT:
02004                 if (is_numeric($date)) {
02005                     return $this->_assign($calc, $this->mktime(0, intval($date), 0, 1, 1, 1970, true),
02006                                                  $this->mktime(0, $minute,       0, 1, 1, 1970, true), false);
02007                 }
02008 
02009                 require_once 'Zend/Date/Exception.php';
02010                 throw new Zend_Date_Exception("invalid date ($date) operand, minute expected", 0, null, $date);
02011                 break;
02012 
02013             case self::SECOND_SHORT:
02014                 if (is_numeric($date)) {
02015                     return $this->_assign($calc, $this->mktime(0, 0, intval($date), 1, 1, 1970, true),
02016                                                  $this->mktime(0, 0, $second,       1, 1, 1970, true), false);
02017                 }
02018 
02019                 require_once 'Zend/Date/Exception.php';
02020                 throw new Zend_Date_Exception("invalid date ($date) operand, second expected", 0, null, $date);
02021                 break;
02022 
02023             // timezone formats
02024             // break intentionally omitted
02025             case self::TIMEZONE_NAME:
02026             case self::TIMEZONE:
02027             case self::TIMEZONE_SECS:
02028                 require_once 'Zend/Date/Exception.php';
02029                 throw new Zend_Date_Exception('timezone not supported', 0, null, $date);
02030                 break;
02031 
02032             case self::DAYLIGHT:
02033                 require_once 'Zend/Date/Exception.php';
02034                 throw new Zend_Date_Exception('daylight not supported', 0, null, $date);
02035                 break;
02036 
02037             case self::GMT_DIFF:
02038             case self::GMT_DIFF_SEP:
02039                 require_once 'Zend/Date/Exception.php';
02040                 throw new Zend_Date_Exception('gmtdiff not supported', 0, null, $date);
02041                 break;
02042 
02043             // date strings
02044             case self::ISO_8601:
02045                 // (-)YYYY-MM-dd
02046                 preg_match('/^(-{0,1}\d{4})-(\d{2})-(\d{2})/', $date, $datematch);
02047                 // (-)YY-MM-dd
02048                 if (empty($datematch)) {
02049                     preg_match('/^(-{0,1}\d{2})-(\d{2})-(\d{2})/', $date, $datematch);
02050                 }
02051                 // (-)YYYYMMdd
02052                 if (empty($datematch)) {
02053                     preg_match('/^(-{0,1}\d{4})(\d{2})(\d{2})/', $date, $datematch);
02054                 }
02055                 // (-)YYMMdd
02056                 if (empty($datematch)) {
02057                     preg_match('/^(-{0,1}\d{2})(\d{2})(\d{2})/', $date, $datematch);
02058                 }
02059                 $tmpdate = $date;
02060                 if (!empty($datematch)) {
02061                     $dateMatchCharCount = iconv_strlen($datematch[0], 'UTF-8');
02062                     $tmpdate = iconv_substr($date,
02063                                             $dateMatchCharCount,
02064                                             iconv_strlen($date, 'UTF-8') - $dateMatchCharCount,
02065                                             'UTF-8');
02066                 }
02067                 // (T)hh:mm:ss
02068                 preg_match('/[T,\s]{0,1}(\d{2}):(\d{2}):(\d{2})/', $tmpdate, $timematch);
02069                 if (empty($timematch)) {
02070                     preg_match('/[T,\s]{0,1}(\d{2})(\d{2})(\d{2})/', $tmpdate, $timematch);
02071                 }
02072                 if (empty($datematch) and empty($timematch)) {
02073                     require_once 'Zend/Date/Exception.php';
02074                     throw new Zend_Date_Exception("unsupported ISO8601 format ($date)", 0, null, $date);
02075                 }
02076                 if (!empty($timematch)) {
02077                     $timeMatchCharCount = iconv_strlen($timematch[0], 'UTF-8');
02078                     $tmpdate = iconv_substr($tmpdate,
02079                                             $timeMatchCharCount,
02080                                             iconv_strlen($tmpdate, 'UTF-8') - $timeMatchCharCount,
02081                                             'UTF-8');
02082                 }
02083                 if (empty($datematch)) {
02084                     $datematch[1] = 1970;
02085                     $datematch[2] = 1;
02086                     $datematch[3] = 1;
02087                 } else if (iconv_strlen($datematch[1], 'UTF-8') == 2) {
02088                     $datematch[1] = self::getFullYear($datematch[1]);
02089                 }
02090                 if (empty($timematch)) {
02091                     $timematch[1] = 0;
02092                     $timematch[2] = 0;
02093                     $timematch[3] = 0;
02094                 }
02095 
02096                 if (($calc == 'set') || ($calc == 'cmp')) {
02097                     --$datematch[2];
02098                     --$month;
02099                     --$datematch[3];
02100                     --$day;
02101                     $datematch[1] -= 1970;
02102                     $year         -= 1970;
02103                 }
02104                 return $this->_assign($calc, $this->mktime($timematch[1], $timematch[2], $timematch[3], 1 + $datematch[2], 1 + $datematch[3], 1970 + $datematch[1], false),
02105                                              $this->mktime($hour,         $minute,       $second,       1 + $month,        1 + $day,          1970 + $year,         false), false);
02106                 break;
02107 
02108             case self::RFC_2822:
02109                 $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);
02110                 if (!$result) {
02111                     require_once 'Zend/Date/Exception.php';
02112                     throw new Zend_Date_Exception("no RFC 2822 format ($date)", 0, null, $date);
02113                 }
02114 
02115                 $months  = $this->_getDigitFromName($match[2]);
02116 
02117                 if (($calc == 'set') || ($calc == 'cmp')) {
02118                     --$months;
02119                     --$month;
02120                     --$match[1];
02121                     --$day;
02122                     $match[3] -= 1970;
02123                     $year     -= 1970;
02124                 }
02125                 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], false),
02126                                              $this->mktime($hour,     $minute,   $second,   1 + $month,  1 + $day,      1970 + $year,     false), false);
02127                 break;
02128 
02129             case self::TIMESTAMP:
02130                 if (is_numeric($date)) {
02131                     return $this->_assign($calc, $date, $this->getUnixTimestamp());
02132                 }
02133 
02134                 require_once 'Zend/Date/Exception.php';
02135                 throw new Zend_Date_Exception("invalid date ($date) operand, timestamp expected", 0, null, $date);
02136                 break;
02137 
02138             // additional formats
02139             // break intentionally omitted
02140             case self::ERA:
02141             case self::ERA_NAME:
02142                 require_once 'Zend/Date/Exception.php';
02143                 throw new Zend_Date_Exception('era not supported', 0, null, $date);
02144                 break;
02145 
02146             case self::DATES:
02147                 try {
02148                     $parsed = Zend_Locale_Format::getDate($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true));
02149 
02150                     if (($calc == 'set') || ($calc == 'cmp')) {
02151                         --$parsed['month'];
02152                         --$month;
02153                         --$parsed['day'];
02154                         --$day;
02155                         $parsed['year'] -= 1970;
02156                         $year  -= 1970;
02157                     }
02158 
02159                     return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true),
02160                                                  $this->mktime(0, 0, 0, 1 + $month,           1 + $day,           1970 + $year,           true), $hour);
02161                 } catch (Zend_Locale_Exception $e) {
02162                     require_once 'Zend/Date/Exception.php';
02163                     throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date);
02164                 }
02165                 break;
02166 
02167             case self::DATE_FULL:
02168                 try {
02169                     $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'full'));
02170                     $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale));
02171 
02172                     if (($calc == 'set') || ($calc == 'cmp')) {
02173                         --$parsed['month'];
02174                         --$month;
02175                         --$parsed['day'];
02176                         --$day;
02177                         $parsed['year'] -= 1970;
02178                         $year  -= 1970;
02179                     }
02180                     return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true),
02181                                                  $this->mktime(0, 0, 0, 1 + $month,           1 + $day,           1970 + $year,           true), $hour);
02182                 } catch (Zend_Locale_Exception $e) {
02183                     require_once 'Zend/Date/Exception.php';
02184                     throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date);
02185                 }
02186                 break;
02187 
02188             case self::DATE_LONG:
02189                 try {
02190                     $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'long'));
02191                     $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale));
02192 
02193                     if (($calc == 'set') || ($calc == 'cmp')){
02194                         --$parsed['month'];
02195                         --$month;
02196                         --$parsed['day'];
02197                         --$day;
02198                         $parsed['year'] -= 1970;
02199                         $year  -= 1970;
02200                     }
02201                     return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true),
02202                                                  $this->mktime(0, 0, 0, 1 + $month,           1 + $day,           1970 + $year,           true), $hour);
02203                 } catch (Zend_Locale_Exception $e) {
02204                     require_once 'Zend/Date/Exception.php';
02205                     throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date);
02206                 }
02207                 break;
02208 
02209             case self::DATE_MEDIUM:
02210                 try {
02211                     $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'medium'));
02212                     $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale));
02213 
02214                     if (($calc == 'set') || ($calc == 'cmp')) {
02215                         --$parsed['month'];
02216                         --$month;
02217                         --$parsed['day'];
02218                         --$day;
02219                         $parsed['year'] -= 1970;
02220                         $year  -= 1970;
02221                     }
02222                     return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true),
02223                                                  $this->mktime(0, 0, 0, 1 + $month,           1 + $day,           1970 + $year,           true), $hour);
02224                 } catch (Zend_Locale_Exception $e) {
02225                     require_once 'Zend/Date/Exception.php';
02226                     throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date);
02227                 }
02228                 break;
02229 
02230             case self::DATE_SHORT:
02231                 try {
02232                     $format = Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'short'));
02233                     $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale));
02234 
02235                     $parsed['year'] = self::getFullYear($parsed['year']);
02236 
02237                     if (($calc == 'set') || ($calc == 'cmp')) {
02238                         --$parsed['month'];
02239                         --$month;
02240                         --$parsed['day'];
02241                         --$day;
02242                         $parsed['year'] -= 1970;
02243                         $year  -= 1970;
02244                     }
02245                     return $this->_assign($calc, $this->mktime(0, 0, 0, 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true),
02246                                                  $this->mktime(0, 0, 0, 1 + $month,           1 + $day,           1970 + $year,           true), $hour);
02247                 } catch (Zend_Locale_Exception $e) {
02248                     require_once 'Zend/Date/Exception.php';
02249                     throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date);
02250                 }
02251                 break;
02252 
02253             case self::TIMES:
02254                 try {
02255                     if ($calc != 'set') {
02256                         $month = 1;
02257                         $day   = 1;
02258                         $year  = 1970;
02259                     }
02260                     $parsed = Zend_Locale_Format::getTime($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true));
02261                     return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true),
02262                                                  $this->mktime($hour,           $minute,           $second,           $month, $day, $year, true), false);
02263                 } catch (Zend_Locale_Exception $e) {
02264                     require_once 'Zend/Date/Exception.php';
02265                     throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date);
02266                 }
02267                 break;
02268 
02269             case self::TIME_FULL:
02270                 try {
02271                     $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'full'));
02272                     $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale));
02273                     if ($calc != 'set') {
02274                         $month = 1;
02275                         $day   = 1;
02276                         $year  = 1970;
02277                     }
02278 
02279                     if (!isset($parsed['second'])) {
02280                         $parsed['second'] = 0;
02281                     }
02282 
02283                     return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true),
02284                                                  $this->mktime($hour,           $minute,           $second,           $month, $day, $year, true), false);
02285                 } catch (Zend_Locale_Exception $e) {
02286                     require_once 'Zend/Date/Exception.php';
02287                     throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date);
02288                 }
02289                 break;
02290 
02291             case self::TIME_LONG:
02292                 try {
02293                     $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'long'));
02294                     $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale));
02295                     if ($calc != 'set') {
02296                         $month = 1;
02297                         $day   = 1;
02298                         $year  = 1970;
02299                     }
02300                     return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true),
02301                                                  $this->mktime($hour,           $minute,           $second,           $month, $day, $year, true), false);
02302                 } catch (Zend_Locale_Exception $e) {
02303                     require_once 'Zend/Date/Exception.php';
02304                     throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date);
02305                 }
02306                 break;
02307 
02308             case self::TIME_MEDIUM:
02309                 try {
02310                     $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'medium'));
02311                     $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale));
02312                     if ($calc != 'set') {
02313                         $month = 1;
02314                         $day   = 1;
02315                         $year  = 1970;
02316                     }
02317                     return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true),
02318                                                  $this->mktime($hour,           $minute,           $second,           $month, $day, $year, true), false);
02319                 } catch (Zend_Locale_Exception $e) {
02320                     require_once 'Zend/Date/Exception.php';
02321                     throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date);
02322                 }
02323                 break;
02324 
02325             case self::TIME_SHORT:
02326                 try {
02327                     $format = Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'short'));
02328                     $parsed = Zend_Locale_Format::getTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale));
02329                     if ($calc != 'set') {
02330                         $month = 1;
02331                         $day   = 1;
02332                         $year  = 1970;
02333                     }
02334 
02335                     if (!isset($parsed['second'])) {
02336                         $parsed['second'] = 0;
02337                     }
02338 
02339                     return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], $month, $day, $year, true),
02340                                                  $this->mktime($hour,           $minute,           $second,           $month, $day, $year, true), false);
02341                 } catch (Zend_Locale_Exception $e) {
02342                     require_once 'Zend/Date/Exception.php';
02343                     throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date);
02344                 }
02345                 break;
02346 
02347             case self::DATETIME:
02348                 try {
02349                     $parsed = Zend_Locale_Format::getDateTime($date, array('locale' => $locale, 'format_type' => 'iso', 'fix_date' => true));
02350                     if (($calc == 'set') || ($calc == 'cmp')) {
02351                         --$parsed['month'];
02352                         --$month;
02353                         --$parsed['day'];
02354                         --$day;
02355                         $parsed['year'] -= 1970;
02356                         $year  -= 1970;
02357                     }
02358                     return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true),
02359                                                  $this->mktime($hour,           $minute,           $second,           1 + $month,           1 + $day,           1970 + $year,           true), $hour);
02360                 } catch (Zend_Locale_Exception $e) {
02361                     require_once 'Zend/Date/Exception.php';
02362                     throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date);
02363                 }
02364                 break;
02365 
02366             case self::DATETIME_FULL:
02367                 try {
02368                     $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'full'));
02369                     $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale));
02370 
02371                     if (($calc == 'set') || ($calc == 'cmp')) {
02372                         --$parsed['month'];
02373                         --$month;
02374                         --$parsed['day'];
02375                         --$day;
02376                         $parsed['year'] -= 1970;
02377                         $year  -= 1970;
02378                     }
02379 
02380                     if (!isset($parsed['second'])) {
02381                         $parsed['second'] = 0;
02382                     }
02383 
02384                     return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true),
02385                                                  $this->mktime($hour,           $minute,           $second,           1 + $month,           1 + $day,           1970 + $year,           true), $hour);
02386                 } catch (Zend_Locale_Exception $e) {
02387                     require_once 'Zend/Date/Exception.php';
02388                     throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date);
02389                 }
02390                 break;
02391 
02392             case self::DATETIME_LONG:
02393                 try {
02394                     $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'long'));
02395                     $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale));
02396 
02397                     if (($calc == 'set') || ($calc == 'cmp')){
02398                         --$parsed['month'];
02399                         --$month;
02400                         --$parsed['day'];
02401                         --$day;
02402                         $parsed['year'] -= 1970;
02403                         $year  -= 1970;
02404                     }
02405                     return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true),
02406                                                  $this->mktime($hour,           $minute,           $second,           1 + $month,           1 + $day,           1970 + $year,           true), $hour);
02407                 } catch (Zend_Locale_Exception $e) {
02408                     require_once 'Zend/Date/Exception.php';
02409                     throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date);
02410                 }
02411                 break;
02412 
02413             case self::DATETIME_MEDIUM:
02414                 try {
02415                     $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'medium'));
02416                     $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale));
02417                     if (($calc == 'set') || ($calc == 'cmp')) {
02418                         --$parsed['month'];
02419                         --$month;
02420                         --$parsed['day'];
02421                         --$day;
02422                         $parsed['year'] -= 1970;
02423                         $year  -= 1970;
02424                     }
02425                     return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true),
02426                                                  $this->mktime($hour,           $minute,           $second,           1 + $month,           1 + $day,           1970 + $year,           true), $hour);
02427                 } catch (Zend_Locale_Exception $e) {
02428                     require_once 'Zend/Date/Exception.php';
02429                     throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date);
02430                 }
02431                 break;
02432 
02433             case self::DATETIME_SHORT:
02434                 try {
02435                     $format = Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'short'));
02436                     $parsed = Zend_Locale_Format::getDateTime($date, array('date_format' => $format, 'format_type' => 'iso', 'locale' => $locale));
02437 
02438                     $parsed['year'] = self::getFullYear($parsed['year']);
02439 
02440                     if (($calc == 'set') || ($calc == 'cmp')) {
02441                         --$parsed['month'];
02442                         --$month;
02443                         --$parsed['day'];
02444                         --$day;
02445                         $parsed['year'] -= 1970;
02446                         $year  -= 1970;
02447                     }
02448 
02449                     if (!isset($parsed['second'])) {
02450                         $parsed['second'] = 0;
02451                     }
02452 
02453                     return $this->_assign($calc, $this->mktime($parsed['hour'], $parsed['minute'], $parsed['second'], 1 + $parsed['month'], 1 + $parsed['day'], 1970 + $parsed['year'], true),
02454                                                  $this->mktime($hour,           $minute,           $second,           1 + $month,           1 + $day,           1970 + $year,           true), $hour);
02455                 } catch (Zend_Locale_Exception $e) {
02456                     require_once 'Zend/Date/Exception.php';
02457                     throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date);
02458                 }
02459                 break;
02460 
02461             // ATOM and RFC_3339 are identical
02462             case self::ATOM:
02463             case self::RFC_3339:
02464                 $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);
02465                 if (!$result) {
02466                     require_once 'Zend/Date/Exception.php';
02467                     throw new Zend_Date_Exception("invalid date ($date) operand, ATOM format expected", 0, null, $date);
02468                 }
02469 
02470                 if (($calc == 'set') || ($calc == 'cmp')) {
02471                     --$match[2];
02472                     --$month;
02473                     --$match[3];
02474                     --$day;
02475                     $match[1] -= 1970;
02476                     $year     -= 1970;
02477                 }
02478                 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $match[2], 1 + $match[3], 1970 + $match[1], true),
02479                                              $this->mktime($hour,     $minute,   $second,   1 + $month,    1 + $day,      1970 + $year,     true), false);
02480                 break;
02481 
02482             case self::COOKIE:
02483                 $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);
02484                 if (!$result) {
02485                     require_once 'Zend/Date/Exception.php';
02486                     throw new Zend_Date_Exception("invalid date ($date) operand, COOKIE format expected", 0, null, $date);
02487                 }
02488                 $matchStartPos = iconv_strpos($match[0], ' ', 0, 'UTF-8') + 1;
02489                 $match[0] = iconv_substr($match[0],
02490                                          $matchStartPos,
02491                                          iconv_strlen($match[0], 'UTF-8') - $matchStartPos,
02492                                          'UTF-8');
02493 
02494                 $months    = $this->_getDigitFromName($match[2]);
02495                 $match[3] = self::getFullYear($match[3]);
02496 
02497                 if (($calc == 'set') || ($calc == 'cmp')) {
02498                     --$months;
02499                     --$month;
02500                     --$match[1];
02501                     --$day;
02502                     $match[3] -= 1970;
02503                     $year     -= 1970;
02504                 }
02505                 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true),
02506                                              $this->mktime($hour,     $minute,   $second,   1 + $month,  1 + $day,      1970 + $year,     true), false);
02507                 break;
02508 
02509             case self::RFC_822:
02510             case self::RFC_1036:
02511                 // new RFC 822 format, identical to RFC 1036 standard
02512                 $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);
02513                 if (!$result) {
02514                     require_once 'Zend/Date/Exception.php';
02515                     throw new Zend_Date_Exception("invalid date ($date) operand, RFC 822 date format expected", 0, null, $date);
02516                 }
02517 
02518                 $months    = $this->_getDigitFromName($match[2]);
02519                 $match[3] = self::getFullYear($match[3]);
02520 
02521                 if (($calc == 'set') || ($calc == 'cmp')) {
02522                     --$months;
02523                     --$month;
02524                     --$match[1];
02525                     --$day;
02526                     $match[3] -= 1970;
02527                     $year     -= 1970;
02528                 }
02529                 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], false),
02530                                              $this->mktime($hour,     $minute,   $second,   1 + $month,  1 + $day,      1970 + $year,     false), false);
02531                 break;
02532 
02533             case self::RFC_850:
02534                 $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);
02535                 if (!$result) {
02536                     require_once 'Zend/Date/Exception.php';
02537                     throw new Zend_Date_Exception("invalid date ($date) operand, RFC 850 date format expected", 0, null, $date);
02538                 }
02539 
02540                 $months    = $this->_getDigitFromName($match[2]);
02541                 $match[3] = self::getFullYear($match[3]);
02542 
02543                 if (($calc == 'set') || ($calc == 'cmp')) {
02544                     --$months;
02545                     --$month;
02546                     --$match[1];
02547                     --$day;
02548                     $match[3] -= 1970;
02549                     $year     -= 1970;
02550                 }
02551                 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true),
02552                                              $this->mktime($hour,     $minute,   $second,   1 + $month,  1 + $day,      1970 + $year,     true), false);
02553                 break;
02554 
02555             case self::RFC_1123:
02556                 $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);
02557                 if (!$result) {
02558                     require_once 'Zend/Date/Exception.php';
02559                     throw new Zend_Date_Exception("invalid date ($date) operand, RFC 1123 date format expected", 0, null, $date);
02560                 }
02561 
02562                 $months  = $this->_getDigitFromName($match[2]);
02563 
02564                 if (($calc == 'set') || ($calc == 'cmp')) {
02565                     --$months;
02566                     --$month;
02567                     --$match[1];
02568                     --$day;
02569                     $match[3] -= 1970;
02570                     $year     -= 1970;
02571                 }
02572                 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true),
02573                                              $this->mktime($hour,     $minute,   $second,   1 + $month,  1 + $day,      1970 + $year,     true), false);
02574                 break;
02575 
02576             case self::RSS:
02577                 $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);
02578                 if (!$result) {
02579                     require_once 'Zend/Date/Exception.php';
02580                     throw new Zend_Date_Exception("invalid date ($date) operand, RSS date format expected", 0, null, $date);
02581                 }
02582 
02583                 $months  = $this->_getDigitFromName($match[2]);
02584                 $match[3] = self::getFullYear($match[3]);
02585 
02586                 if (($calc == 'set') || ($calc == 'cmp')) {
02587                     --$months;
02588                     --$month;
02589                     --$match[1];
02590                     --$day;
02591                     $match[3] -= 1970;
02592                     $year  -= 1970;
02593                 }
02594                 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $months, 1 + $match[1], 1970 + $match[3], true),
02595                                              $this->mktime($hour,     $minute,   $second,   1 + $month,  1 + $day,      1970 + $year,     true), false);
02596                 break;
02597 
02598             case self::W3C:
02599                 $result = preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})[+-]{1}\d{2}:\d{2}$/', $date, $match);
02600                 if (!$result) {
02601                     require_once 'Zend/Date/Exception.php';
02602                     throw new Zend_Date_Exception("invalid date ($date) operand, W3C date format expected", 0, null, $date);
02603                 }
02604 
02605                 if (($calc == 'set') || ($calc == 'cmp')) {
02606                     --$match[2];
02607                     --$month;
02608                     --$match[3];
02609                     --$day;
02610                     $match[1] -= 1970;
02611                     $year     -= 1970;
02612                 }
02613                 return $this->_assign($calc, $this->mktime($match[4], $match[5], $match[6], 1 + $match[2], 1 + $match[3], 1970 + $match[1], true),
02614                                              $this->mktime($hour,     $minute,   $second,   1 + $month,    1 + $day,      1970 + $year,     true), false);
02615                 break;
02616 
02617             default:
02618                 if (!is_numeric($date) || !empty($part)) {
02619                     try {
02620                         if (empty($part)) {
02621                             $part  = Zend_Locale_Format::getDateFormat($locale) . " ";
02622                             $part .= Zend_Locale_Format::getTimeFormat($locale);
02623                         }
02624 
02625                         $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $part, 'locale' => $locale, 'fix_date' => true, 'format_type' => 'iso'));
02626                         if ((strpos(strtoupper($part), 'YY') !== false) and (strpos(strtoupper($part), 'YYYY') === false)) {
02627                             $parsed['year'] = self::getFullYear($parsed['year']);
02628                         }
02629 
02630                         if (($calc == 'set') || ($calc == 'cmp')) {
02631                             if (isset($parsed['month'])) {
02632                                 --$parsed['month'];
02633                             } else {
02634                                 $parsed['month'] = 0;
02635                             }
02636 
02637                             if (isset($parsed['day'])) {
02638                                 --$parsed['day'];
02639                             } else {
02640                                 $parsed['day'] = 0;
02641                             }
02642 
02643                             if (isset($parsed['year'])) {
02644                                 $parsed['year'] -= 1970;
02645                             } else {
02646                                 $parsed['year'] = 0;
02647                             }
02648                         }
02649 
02650                         return $this->_assign($calc, $this->mktime(
02651                             isset($parsed['hour']) ? $parsed['hour'] : 0,
02652                             isset($parsed['minute']) ? $parsed['minute'] : 0,
02653                             isset($parsed['second']) ? $parsed['second'] : 0,
02654                             isset($parsed['month']) ? (1 + $parsed['month']) : 1,
02655                             isset($parsed['day']) ? (1 + $parsed['day']) : 1,
02656                             isset($parsed['year']) ? (1970 + $parsed['year']) : 1970,
02657                             false), $this->getUnixTimestamp(), false);
02658                     } catch (Zend_Locale_Exception $e) {
02659                         if (!is_numeric($date)) {
02660                             require_once 'Zend/Date/Exception.php';
02661                             throw new Zend_Date_Exception($e->getMessage(), 0, $e, $date);
02662                         }
02663                     }
02664                 }
02665 
02666                 return $this->_assign($calc, $date, $this->getUnixTimestamp(), false);
02667                 break;
02668         }
02669     }
02670 
02682     public function equals($date, $part = self::TIMESTAMP, $locale = null)
02683     {
02684         $result = $this->compare($date, $part, $locale);
02685 
02686         if ($result == 0) {
02687             return true;
02688         }
02689 
02690         return false;
02691     }
02692 
02704     public function isEarlier($date, $part = null, $locale = null)
02705     {
02706         $result = $this->compare($date, $part, $locale);
02707 
02708         if ($result == -1) {
02709             return true;
02710         }
02711 
02712         return false;
02713     }
02714 
02727     public function isLater($date, $part = null, $locale = null)
02728     {
02729         $result = $this->compare($date, $part, $locale);
02730 
02731         if ($result == 1) {
02732             return true;
02733         }
02734 
02735         return false;
02736     }
02737 
02746     public function getTime($locale = null)
02747     {
02748         if (self::$_options['format_type'] == 'php') {
02749             $format = 'H:i:s';
02750         } else {
02751             $format = self::TIME_MEDIUM;
02752         }
02753 
02754         return $this->copyPart($format, $locale);
02755     }
02756 
02767     private function _time($calc, $time, $format, $locale)
02768     {
02769         if ($time === null) {
02770             require_once 'Zend/Date/Exception.php';
02771             throw new Zend_Date_Exception('parameter $time must be set, null is not allowed');
02772         }
02773 
02774         if ($time instanceof Zend_Date) {
02775             // extract time from object
02776             $time = $time->toString('HH:mm:ss', 'iso');
02777         } else {
02778             if (is_array($time)) {
02779                 if ((isset($time['hour']) === true) or (isset($time['minute']) === true) or
02780                     (isset($time['second']) === true)) {
02781                     $parsed = $time;
02782                 } else {
02783                     require_once 'Zend/Date/Exception.php';
02784                     throw new Zend_Date_Exception("no hour, minute or second given in array");
02785                 }
02786             } else {
02787                 if (self::$_options['format_type'] == 'php') {
02788                     $format = Zend_Locale_Format::convertPhpToIsoFormat($format);
02789                 }
02790                 try {
02791                     if ($locale === null) {
02792                         $locale = $this->getLocale();
02793                     }
02794 
02795                     $parsed = Zend_Locale_Format::getTime($time, array('date_format' => $format, 'locale' => $locale, 'format_type' => 'iso'));
02796                 } catch (Zend_Locale_Exception $e) {
02797                     require_once 'Zend/Date/Exception.php';
02798                     throw new Zend_Date_Exception($e->getMessage(), 0, $e);
02799                 }
02800             }
02801 
02802             if (!array_key_exists('hour', $parsed)) {
02803                 $parsed['hour'] = 0;
02804             }
02805 
02806             if (!array_key_exists('minute', $parsed)) {
02807                 $parsed['minute'] = 0;
02808             }
02809 
02810             if (!array_key_exists('second', $parsed)) {
02811                 $parsed['second'] = 0;
02812             }
02813 
02814             $time  = str_pad($parsed['hour'], 2, '0', STR_PAD_LEFT) . ":";
02815             $time .= str_pad($parsed['minute'], 2, '0', STR_PAD_LEFT) . ":";
02816             $time .= str_pad($parsed['second'], 2, '0', STR_PAD_LEFT);
02817         }
02818 
02819         $return = $this->_calcdetail($calc, $time, self::TIMES, 'de');
02820         if ($calc != 'cmp') {
02821             return $this;
02822         }
02823 
02824         return $return;
02825     }
02826 
02827 
02840     public function setTime($time, $format = null, $locale = null)
02841     {
02842         return $this->_time('set', $time, $format, $locale);
02843     }
02844 
02845 
02858     public function addTime($time, $format = null, $locale = null)
02859     {
02860         return $this->_time('add', $time, $format, $locale);
02861     }
02862 
02863 
02876     public function subTime($time, $format = null, $locale = null)
02877     {
02878         return $this->_time('sub', $time, $format, $locale);
02879     }
02880 
02881 
02894     public function compareTime($time, $format = null, $locale = null)
02895     {
02896         return $this->_time('cmp', $time, $format, $locale);
02897     }
02898 
02905     public function getDate($locale = null)
02906     {
02907         $orig = self::$_options['format_type'];
02908         if (self::$_options['format_type'] == 'php') {
02909             self::$_options['format_type'] = 'iso';
02910         }
02911 
02912         $date = $this->copyPart(self::DATE_MEDIUM, $locale);
02913         $date->addTimestamp($this->getGmtOffset());
02914         self::$_options['format_type'] = $orig;
02915 
02916         return $date;
02917     }
02918 
02929     private function _date($calc, $date, $format, $locale)
02930     {
02931         if ($date === null) {
02932             require_once 'Zend/Date/Exception.php';
02933             throw new Zend_Date_Exception('parameter $date must be set, null is not allowed');
02934         }
02935 
02936         if ($date instanceof Zend_Date) {
02937             // extract date from object
02938             $date = $date->toString('d.M.y', 'iso');
02939         } else {
02940             if (is_array($date)) {
02941                 if ((isset($date['year']) === true) or (isset($date['month']) === true) or
02942                     (isset($date['day']) === true)) {
02943                     $parsed = $date;
02944                 } else {
02945                     require_once 'Zend/Date/Exception.php';
02946                     throw new Zend_Date_Exception("no day,month or year given in array");
02947                 }
02948             } else {
02949                 if ((self::$_options['format_type'] == 'php') && !defined($format)) {
02950                     $format = Zend_Locale_Format::convertPhpToIsoFormat($format);
02951                 }
02952                 try {
02953                     if ($locale === null) {
02954                         $locale = $this->getLocale();
02955                     }
02956 
02957                     $parsed = Zend_Locale_Format::getDate($date, array('date_format' => $format, 'locale' => $locale, 'format_type' => 'iso'));
02958                     if ((strpos(strtoupper($format), 'YY') !== false) and (strpos(strtoupper($format), 'YYYY') === false)) {
02959                         $parsed['year'] = self::getFullYear($parsed['year']);
02960                     }
02961                 } catch (Zend_Locale_Exception $e) {
02962                     require_once 'Zend/Date/Exception.php';
02963                     throw new Zend_Date_Exception($e->getMessage(), 0, $e);
02964                 }
02965             }
02966 
02967             if (!array_key_exists('day', $parsed)) {
02968                 $parsed['day'] = 1;
02969             }
02970 
02971             if (!array_key_exists('month', $parsed)) {
02972                 $parsed['month'] = 1;
02973             }
02974 
02975             if (!array_key_exists('year', $parsed)) {
02976                 $parsed['year'] = 0;
02977             }
02978 
02979             $date  = $parsed['day'] . "." . $parsed['month'] . "." . $parsed['year'];
02980         }
02981 
02982         $return = $this->_calcdetail($calc, $date, self::DATE_MEDIUM, 'de');
02983         if ($calc != 'cmp') {
02984             return $this;
02985         }
02986         return $return;
02987     }
02988 
02989 
03002     public function setDate($date, $format = null, $locale = null)
03003     {
03004         return $this->_date('set', $date, $format, $locale);
03005     }
03006 
03007 
03020     public function addDate($date, $format = null, $locale = null)
03021     {
03022         return $this->_date('add', $date, $format, $locale);
03023     }
03024 
03025 
03039     public function subDate($date, $format = null, $locale = null)
03040     {
03041         return $this->_date('sub', $date, $format, $locale);
03042     }
03043 
03044 
03058     public function compareDate($date, $format = null, $locale = null)
03059     {
03060         return $this->_date('cmp', $date, $format, $locale);
03061     }
03062 
03063 
03073     public function getIso($locale = null)
03074     {
03075         return $this->toString(self::ISO_8601, 'iso', $locale);
03076     }
03077 
03078 
03090     public function setIso($date, $locale = null)
03091     {
03092         return $this->_calcvalue('set', $date, 'iso', self::ISO_8601, $locale);
03093     }
03094 
03095 
03107     public function addIso($date, $locale = null)
03108     {
03109         return $this->_calcvalue('add', $date, 'iso', self::ISO_8601, $locale);
03110     }
03111 
03112 
03124     public function subIso($date, $locale = null)
03125     {
03126         return $this->_calcvalue('sub', $date, 'iso', self::ISO_8601, $locale);
03127     }
03128 
03129 
03141     public function compareIso($date, $locale = null)
03142     {
03143         return $this->_calcvalue('cmp', $date, 'iso', self::ISO_8601, $locale);
03144     }
03145 
03146 
03154     public function getArpa($locale = null)
03155     {
03156         if (self::$_options['format_type'] == 'php') {
03157             $format = 'D\, d M y H\:i\:s O';
03158         } else {
03159             $format = self::RFC_822;
03160         }
03161 
03162         return $this->toString($format, 'iso', $locale);
03163     }
03164 
03165 
03177     public function setArpa($date, $locale = null)
03178     {
03179         return $this->_calcvalue('set', $date, 'arpa', self::RFC_822, $locale);
03180     }
03181 
03182 
03195     public function addArpa($date, $locale = null)
03196     {
03197         return $this->_calcvalue('add', $date, 'arpa', self::RFC_822, $locale);
03198     }
03199 
03200 
03213     public function subArpa($date, $locale = null)
03214     {
03215         return $this->_calcvalue('sub', $date, 'arpa', self::RFC_822, $locale);
03216     }
03217 
03218 
03231     public function compareArpa($date, $locale = null)
03232     {
03233         return $this->_calcvalue('cmp', $date, 'arpa', self::RFC_822, $locale);
03234     }
03235 
03236 
03243     private function _checkLocation($location)
03244     {
03245         if (!isset($location['longitude']) or !isset($location['latitude'])) {
03246             require_once 'Zend/Date/Exception.php';
03247             throw new Zend_Date_Exception('Location must include \'longitude\' and \'latitude\'', 0, null, $location);
03248         }
03249         if (($location['longitude'] > 180) or ($location['longitude'] < -180)) {
03250             require_once 'Zend/Date/Exception.php';
03251             throw new Zend_Date_Exception('Longitude must be between -180 and 180', 0, null, $location);
03252         }
03253         if (($location['latitude'] > 90) or ($location['latitude'] < -90)) {
03254             require_once 'Zend/Date/Exception.php';
03255             throw new Zend_Date_Exception('Latitude must be between -90 and 90', 0, null, $location);
03256         }
03257 
03258         if (!isset($location['horizon'])){
03259             $location['horizon'] = 'effective';
03260         }
03261 
03262         switch ($location['horizon']) {
03263             case 'civil' :
03264                 return -0.104528;
03265                 break;
03266             case 'nautic' :
03267                 return -0.207912;
03268                 break;
03269             case 'astronomic' :
03270                 return -0.309017;
03271                 break;
03272             default :
03273                 return -0.0145439;
03274                 break;
03275         }
03276     }
03277 
03278 
03290     public function getSunrise($location)
03291     {
03292         $horizon = $this->_checkLocation($location);
03293         $result = clone $this;
03294         $result->set($this->calcSun($location, $horizon, true), self::TIMESTAMP);
03295         return $result;
03296     }
03297 
03298 
03310     public function getSunset($location)
03311     {
03312         $horizon = $this->_checkLocation($location);
03313         $result = clone $this;
03314         $result->set($this->calcSun($location, $horizon, false), self::TIMESTAMP);
03315         return $result;
03316     }
03317 
03318 
03330     public function getSunInfo($location)
03331     {
03332         $suninfo = array();
03333         for ($i = 0; $i < 4; ++$i) {
03334             switch ($i) {
03335                 case 0 :
03336                     $location['horizon'] = 'effective';
03337                     break;
03338                 case 1 :
03339                     $location['horizon'] = 'civil';
03340                     break;
03341                 case 2 :
03342                     $location['horizon'] = 'nautic';
03343                     break;
03344                 case 3 :
03345                     $location['horizon'] = 'astronomic';
03346                     break;
03347             }
03348             $horizon = $this->_checkLocation($location);
03349             $result = clone $this;
03350             $result->set($this->calcSun($location, $horizon, true), self::TIMESTAMP);
03351             $suninfo['sunrise'][$location['horizon']] = $result;
03352             $result = clone $this;
03353             $result->set($this->calcSun($location, $horizon, false), self::TIMESTAMP);
03354             $suninfo['sunset'][$location['horizon']]  = $result;
03355         }
03356         return $suninfo;
03357     }
03358 
03359 
03366     public static function checkLeapYear($year)
03367     {
03368         if ($year instanceof Zend_Date) {
03369             $year = (int) $year->toString(self::YEAR, 'iso');
03370         }
03371 
03372         if (is_array($year)) {
03373             if (isset($year['year']) === true) {
03374                 $year = $year['year'];
03375             } else {
03376                 require_once 'Zend/Date/Exception.php';
03377                 throw new Zend_Date_Exception("no year given in array");
03378             }
03379         }
03380 
03381         if (!is_numeric($year)) {
03382             require_once 'Zend/Date/Exception.php';
03383             throw new Zend_Date_Exception("year ($year) has to be integer for checkLeapYear()", 0, null, $year);
03384         }
03385 
03386         return (bool) parent::isYearLeapYear($year);
03387     }
03388 
03389 
03395     public function isLeapYear()
03396     {
03397         return self::checkLeapYear($this);
03398     }
03399 
03400 
03406     public function isToday()
03407     {
03408         $today = $this->date('Ymd', $this->_getTime());
03409         $day   = $this->date('Ymd', $this->getUnixTimestamp());
03410         return ($today == $day);
03411     }
03412 
03413 
03419     public function isYesterday()
03420     {
03421         list($year, $month, $day) = explode('-', $this->date('Y-m-d', $this->_getTime()));
03422         // adjusts for leap days and DST changes that are timezone specific
03423         $yesterday = $this->date('Ymd', $this->mktime(0, 0, 0, $month, $day -1, $year));
03424         $day   = $this->date('Ymd', $this->getUnixTimestamp());
03425         return $day == $yesterday;
03426     }
03427 
03428 
03434     public function isTomorrow()
03435     {
03436         list($year, $month, $day) = explode('-', $this->date('Y-m-d', $this->_getTime()));
03437         // adjusts for leap days and DST changes that are timezone specific
03438         $tomorrow = $this->date('Ymd', $this->mktime(0, 0, 0, $month, $day +1, $year));
03439         $day   = $this->date('Ymd', $this->getUnixTimestamp());
03440         return $day == $tomorrow;
03441     }
03442 
03449     public static function now($locale = null)
03450     {
03451         return new Zend_Date(time(), self::TIMESTAMP, $locale);
03452     }
03453 
03464     private function _calcdetail($calc, $date, $type, $locale)
03465     {
03466         $old = false;
03467         if (self::$_options['format_type'] == 'php') {
03468             self::$_options['format_type'] = 'iso';
03469             $old = true;
03470         }
03471 
03472         switch($calc) {
03473             case 'set' :
03474                 $return = $this->set($date, $type, $locale);
03475                 break;
03476             case 'add' :
03477                 $return = $this->add($date, $type, $locale);
03478                 break;
03479             case 'sub' :
03480                 $return = $this->sub($date, $type, $locale);
03481                 break;
03482             default :
03483                 $return = $this->compare($date, $type, $locale);
03484                 break;
03485         }
03486 
03487         if ($old) {
03488             self::$_options['format_type'] = 'php';
03489         }
03490 
03491         return $return;
03492     }
03493 
03503     private function _calcvalue($calc, $value, $type, $parameter, $locale)
03504     {
03505         if ($value === null) {
03506             require_once 'Zend/Date/Exception.php';
03507             throw new Zend_Date_Exception("parameter $type must be set, null is not allowed");
03508         }
03509 
03510         if ($locale === null) {
03511             $locale = $this->getLocale();
03512         }
03513 
03514         if ($value instanceof Zend_Date) {
03515             // extract value from object
03516             $value = $value->toString($parameter, 'iso', $locale);
03517         } else if (!is_array($value) && !is_numeric($value) && ($type != 'iso') && ($type != 'arpa')) {
03518             require_once 'Zend/Date/Exception.php';
03519             throw new Zend_Date_Exception("invalid $type ($value) operand", 0, null, $value);
03520         }
03521 
03522         $return = $this->_calcdetail($calc, $value, $parameter, $locale);
03523         if ($calc != 'cmp') {
03524             return $this;
03525         }
03526         return $return;
03527     }
03528 
03529 
03537     public function getYear($locale = null)
03538     {
03539         if (self::$_options['format_type'] == 'php') {
03540             $format = 'Y';
03541         } else {
03542             $format = self::YEAR;
03543         }
03544 
03545         return $this->copyPart($format, $locale);
03546     }
03547 
03548 
03562     public function setYear($year, $locale = null)
03563     {
03564         return $this->_calcvalue('set', $year, 'year', self::YEAR, $locale);
03565     }
03566 
03567 
03581     public function addYear($year, $locale = null)
03582     {
03583         return $this->_calcvalue('add', $year, 'year', self::YEAR, $locale);
03584     }
03585 
03586 
03600     public function subYear($year, $locale = null)
03601     {
03602         return $this->_calcvalue('sub', $year, 'year', self::YEAR, $locale);
03603     }
03604 
03605 
03616     public function compareYear($year, $locale = null)
03617     {
03618         return $this->_calcvalue('cmp', $year, 'year', self::YEAR, $locale);
03619     }
03620 
03621 
03629     public function getMonth($locale = null)
03630     {
03631         if (self::$_options['format_type'] == 'php') {
03632             $format = 'm';
03633         } else {
03634             $format = self::MONTH;
03635         }
03636 
03637         return $this->copyPart($format, $locale);
03638     }
03639 
03640 
03650     private function _month($calc, $month, $locale)
03651     {
03652         if ($month === null) {
03653             require_once 'Zend/Date/Exception.php';
03654             throw new Zend_Date_Exception('parameter $month must be set, null is not allowed');
03655         }
03656 
03657         if ($locale === null) {
03658             $locale = $this->getLocale();
03659         }
03660 
03661         if ($month instanceof Zend_Date) {
03662             // extract month from object
03663             $found = $month->toString(self::MONTH_SHORT, 'iso', $locale);
03664         } else {
03665             if (is_numeric($month)) {
03666                 $found = $month;
03667             } else if (is_array($month)) {
03668                 if (isset($month['month']) === true) {
03669                     $month = $month['month'];
03670                 } else {
03671                     require_once 'Zend/Date/Exception.php';
03672                     throw new Zend_Date_Exception("no month given in array");
03673                 }
03674             } else {
03675                 $monthlist  = Zend_Locale_Data::getList($locale, 'month');
03676                 $monthlist2 = Zend_Locale_Data::getList($locale, 'month', array('gregorian', 'format', 'abbreviated'));
03677 
03678                 $monthlist = array_merge($monthlist, $monthlist2);
03679                 $found = 0;
03680                 $cnt = 0;
03681                 foreach ($monthlist as $key => $value) {
03682                     if (strtoupper($value) == strtoupper($month)) {
03683                         $found = ($key % 12) + 1;
03684                         break;
03685                     }
03686                     ++$cnt;
03687                 }
03688                 if ($found == 0) {
03689                     foreach ($monthlist2 as $key => $value) {
03690                         if (strtoupper(iconv_substr($value, 0, 1, 'UTF-8')) == strtoupper($month)) {
03691                             $found = $key + 1;
03692                             break;
03693                         }
03694                         ++$cnt;
03695                     }
03696                 }
03697                 if ($found == 0) {
03698                     require_once 'Zend/Date/Exception.php';
03699                     throw new Zend_Date_Exception("unknown month name ($month)", 0, null, $month);
03700                 }
03701             }
03702         }
03703         $return = $this->_calcdetail($calc, $found, self::MONTH_SHORT, $locale);
03704         if ($calc != 'cmp') {
03705             return $this;
03706         }
03707         return $return;
03708     }
03709 
03710 
03724     public function setMonth($month, $locale = null)
03725     {
03726         return $this->_month('set', $month, $locale);
03727     }
03728 
03729 
03743     public function addMonth($month, $locale = null)
03744     {
03745         return $this->_month('add', $month, $locale);
03746     }
03747 
03748 
03762     public function subMonth($month, $locale = null)
03763     {
03764         return $this->_month('sub', $month, $locale);
03765     }
03766 
03767 
03778     public function compareMonth($month, $locale = null)
03779     {
03780         return $this->_month('cmp', $month, $locale);
03781     }
03782 
03783 
03791     public function getDay($locale = null)
03792     {
03793         return $this->copyPart(self::DAY_SHORT, $locale);
03794     }
03795 
03796 
03805     private function _day($calc, $day, $locale)
03806     {
03807         if ($day === null) {
03808             require_once 'Zend/Date/Exception.php';
03809             throw new Zend_Date_Exception('parameter $day must be set, null is not allowed');
03810         }
03811 
03812         if ($locale === null) {
03813             $locale = $this->getLocale();
03814         }
03815 
03816         if ($day instanceof Zend_Date) {
03817             $day = $day->toString(self::DAY_SHORT, 'iso', $locale);
03818         }
03819 
03820         if (is_numeric($day)) {
03821             $type = self::DAY_SHORT;
03822         } else if (is_array($day)) {
03823             if (isset($day['day']) === true) {
03824                 $day = $day['day'];
03825                 $type = self::WEEKDAY;
03826             } else {
03827                 require_once 'Zend/Date/Exception.php';
03828                 throw new Zend_Date_Exception("no day given in array");
03829             }
03830         } else {
03831             switch (iconv_strlen($day, 'UTF-8')) {
03832                 case 1 :
03833                    $type = self::WEEKDAY_NARROW;
03834                     break;
03835                 case 2:
03836                     $type = self::WEEKDAY_NAME;
03837                     break;
03838                 case 3:
03839                     $type = self::WEEKDAY_SHORT;
03840                     break;
03841                 default:
03842                     $type = self::WEEKDAY;
03843                     break;
03844             }
03845         }
03846         $return = $this->_calcdetail($calc, $day, $type, $locale);
03847         if ($calc != 'cmp') {
03848             return $this;
03849         }
03850         return $return;
03851     }
03852 
03853 
03868     public function setDay($day, $locale = null)
03869     {
03870         return $this->_day('set', $day, $locale);
03871     }
03872 
03873 
03886     public function addDay($day, $locale = null)
03887     {
03888         return $this->_day('add', $day, $locale);
03889     }
03890 
03891 
03904     public function subDay($day, $locale = null)
03905     {
03906         return $this->_day('sub', $day, $locale);
03907     }
03908 
03909 
03920     public function compareDay($day, $locale = null)
03921     {
03922         return $this->_day('cmp', $day, $locale);
03923     }
03924 
03925 
03934     public function getWeekday($locale = null)
03935     {
03936         if (self::$_options['format_type'] == 'php') {
03937             $format = 'l';
03938         } else {
03939             $format = self::WEEKDAY;
03940         }
03941 
03942         return $this->copyPart($format, $locale);
03943     }
03944 
03945 
03955     private function _weekday($calc, $weekday, $locale)
03956     {
03957         if ($weekday === null) {
03958             require_once 'Zend/Date/Exception.php';
03959             throw new Zend_Date_Exception('parameter $weekday must be set, null is not allowed');
03960         }
03961 
03962         if ($locale === null) {
03963             $locale = $this->getLocale();
03964         }
03965 
03966         if ($weekday instanceof Zend_Date) {
03967             $weekday = $weekday->toString(self::WEEKDAY_8601, 'iso', $locale);
03968         }
03969 
03970         if (is_numeric($weekday)) {
03971             $type = self::WEEKDAY_8601;
03972         } else if (is_array($weekday)) {
03973             if (isset($weekday['weekday']) === true) {
03974                 $weekday = $weekday['weekday'];
03975                 $type = self::WEEKDAY;
03976             } else {
03977                 require_once 'Zend/Date/Exception.php';
03978                 throw new Zend_Date_Exception("no weekday given in array");
03979             }
03980         } else {
03981             switch(iconv_strlen($weekday, 'UTF-8')) {
03982                 case 1:
03983                    $type = self::WEEKDAY_NARROW;
03984                     break;
03985                 case 2:
03986                     $type = self::WEEKDAY_NAME;
03987                     break;
03988                 case 3:
03989                     $type = self::WEEKDAY_SHORT;
03990                     break;
03991                 default:
03992                     $type = self::WEEKDAY;
03993                     break;
03994             }
03995         }
03996         $return = $this->_calcdetail($calc, $weekday, $type, $locale);
03997         if ($calc != 'cmp') {
03998             return $this;
03999         }
04000         return $return;
04001     }
04002 
04003 
04016     public function setWeekday($weekday, $locale = null)
04017     {
04018         return $this->_weekday('set', $weekday, $locale);
04019     }
04020 
04021 
04036     public function addWeekday($weekday, $locale = null)
04037     {
04038         return $this->_weekday('add', $weekday, $locale);
04039     }
04040 
04041 
04056     public function subWeekday($weekday, $locale = null)
04057     {
04058         return $this->_weekday('sub', $weekday, $locale);
04059     }
04060 
04061 
04072     public function compareWeekday($weekday, $locale = null)
04073     {
04074         return $this->_weekday('cmp', $weekday, $locale);
04075     }
04076 
04077 
04085     public function getDayOfYear($locale = null)
04086     {
04087         if (self::$_options['format_type'] == 'php') {
04088             $format = 'D';
04089         } else {
04090             $format = self::DAY_OF_YEAR;
04091         }
04092 
04093         return $this->copyPart($format, $locale);
04094     }
04095 
04096 
04108     public function setDayOfYear($day, $locale = null)
04109     {
04110         return $this->_calcvalue('set', $day, 'day of year', self::DAY_OF_YEAR, $locale);
04111     }
04112 
04113 
04125     public function addDayOfYear($day, $locale = null)
04126     {
04127         return $this->_calcvalue('add', $day, 'day of year', self::DAY_OF_YEAR, $locale);
04128     }
04129 
04130 
04142     public function subDayOfYear($day, $locale = null)
04143     {
04144         return $this->_calcvalue('sub', $day, 'day of year', self::DAY_OF_YEAR, $locale);
04145     }
04146 
04147 
04158     public function compareDayOfYear($day, $locale = null)
04159     {
04160         return $this->_calcvalue('cmp', $day, 'day of year', self::DAY_OF_YEAR, $locale);
04161     }
04162 
04163 
04171     public function getHour($locale = null)
04172     {
04173         return $this->copyPart(self::HOUR, $locale);
04174     }
04175 
04176 
04188     public function setHour($hour, $locale = null)
04189     {
04190         return $this->_calcvalue('set', $hour, 'hour', self::HOUR_SHORT, $locale);
04191     }
04192 
04193 
04205     public function addHour($hour, $locale = null)
04206     {
04207         return $this->_calcvalue('add', $hour, 'hour', self::HOUR_SHORT, $locale);
04208     }
04209 
04210 
04222     public function subHour($hour, $locale = null)
04223     {
04224         return $this->_calcvalue('sub', $hour, 'hour', self::HOUR_SHORT, $locale);
04225     }
04226 
04227 
04238     public function compareHour($hour, $locale = null)
04239     {
04240         return $this->_calcvalue('cmp', $hour, 'hour', self::HOUR_SHORT, $locale);
04241     }
04242 
04243 
04251     public function getMinute($locale = null)
04252     {
04253         if (self::$_options['format_type'] == 'php') {
04254             $format = 'i';
04255         } else {
04256             $format = self::MINUTE;
04257         }
04258 
04259         return $this->copyPart($format, $locale);
04260     }
04261 
04262 
04274     public function setMinute($minute, $locale = null)
04275     {
04276         return $this->_calcvalue('set', $minute, 'minute', self::MINUTE_SHORT, $locale);
04277     }
04278 
04279 
04291     public function addMinute($minute, $locale = null)
04292     {
04293         return $this->_calcvalue('add', $minute, 'minute', self::MINUTE_SHORT, $locale);
04294     }
04295 
04296 
04308     public function subMinute($minute, $locale = null)
04309     {
04310         return $this->_calcvalue('sub', $minute, 'minute', self::MINUTE_SHORT, $locale);
04311     }
04312 
04313 
04324     public function compareMinute($minute, $locale = null)
04325     {
04326         return $this->_calcvalue('cmp', $minute, 'minute', self::MINUTE_SHORT, $locale);
04327     }
04328 
04329 
04337     public function getSecond($locale = null)
04338     {
04339         if (self::$_options['format_type'] == 'php') {
04340             $format = 's';
04341         } else {
04342             $format = self::SECOND;
04343         }
04344 
04345         return $this->copyPart($format, $locale);
04346     }
04347 
04348 
04360     public function setSecond($second, $locale = null)
04361     {
04362         return $this->_calcvalue('set', $second, 'second', self::SECOND_SHORT, $locale);
04363     }
04364 
04365 
04377     public function addSecond($second, $locale = null)
04378     {
04379         return $this->_calcvalue('add', $second, 'second', self::SECOND_SHORT, $locale);
04380     }
04381 
04382 
04394     public function subSecond($second, $locale = null)
04395     {
04396         return $this->_calcvalue('sub', $second, 'second', self::SECOND_SHORT, $locale);
04397     }
04398 
04399 
04410     public function compareSecond($second, $locale = null)
04411     {
04412         return $this->_calcvalue('cmp', $second, 'second', self::SECOND_SHORT, $locale);
04413     }
04414 
04415 
04421     public function getFractionalPrecision()
04422     {
04423         return $this->_precision;
04424     }
04425 
04426 
04434     public function setFractionalPrecision($precision)
04435     {
04436         if (!intval($precision) or ($precision < 0) or ($precision > 9)) {
04437             require_once 'Zend/Date/Exception.php';
04438             throw new Zend_Date_Exception("precision ($precision) must be a positive integer less than 10", 0, null, $precision);
04439         }
04440 
04441         $this->_precision = (int) $precision;
04442         if ($this->_precision < strlen($this->_fractional)) {
04443             $this->_fractional = substr($this->_fractional, 0, $this->_precision);
04444         } else {
04445             $this->_fractional = str_pad($this->_fractional, $this->_precision, '0', STR_PAD_RIGHT);
04446         }
04447 
04448         return $this;
04449     }
04450 
04451 
04457     public function getMilliSecond()
04458     {
04459         return $this->_fractional;
04460     }
04461 
04462 
04471     public function setMilliSecond($milli = null, $precision = null)
04472     {
04473         if ($milli === null) {
04474             list($milli, $time) = explode(" ", microtime());
04475             $milli = intval($milli);
04476             $precision = 6;
04477         } else if (!is_numeric($milli)) {
04478             require_once 'Zend/Date/Exception.php';
04479             throw new Zend_Date_Exception("invalid milli second ($milli) operand", 0, null, $milli);
04480         }
04481 
04482         if ($precision === null) {
04483             $precision = $this->_precision;
04484         }
04485 
04486         if (!is_int($precision) || $precision < 1 || $precision > 9) {
04487             require_once 'Zend/Date/Exception.php';
04488             throw new Zend_Date_Exception("precision ($precision) must be a positive integer less than 10", 0, null, $precision);
04489         }
04490 
04491         $this->_fractional = 0;
04492         $this->addMilliSecond($milli, $precision);
04493         return $this;
04494     }
04495 
04496 
04504     public function addMilliSecond($milli = null, $precision = null)
04505     {
04506         if ($milli === null) {
04507             list($milli, $time) = explode(" ", microtime());
04508             $milli = intval($milli);
04509         } else if (!is_numeric($milli)) {
04510             require_once 'Zend/Date/Exception.php';
04511             throw new Zend_Date_Exception("invalid milli second ($milli) operand", 0, null, $milli);
04512         }
04513 
04514         if ($precision === null) {
04515             $precision = strlen($milli);
04516             if ($milli < 0) {
04517                 --$precision;
04518             }
04519         }
04520 
04521         if (!is_int($precision) || $precision < 1 || $precision > 9) {
04522             require_once 'Zend/Date/Exception.php';
04523             throw new Zend_Date_Exception("precision ($precision) must be a positive integer less than 10", 0, null, $precision);
04524         }
04525 
04526         $this->_fractional += $milli;
04527 
04528         // Add/sub milliseconds + add/sub seconds
04529         $max = pow(10, $this->_precision);
04530         // Milli includes seconds
04531         if ($this->_fractional >= $max) {
04532             while ($this->_fractional >= $max) {
04533                 $this->addSecond(1);
04534                 $this->_fractional -= $max;
04535             }
04536         }
04537 
04538         if ($this->_fractional < 0) {
04539             while ($this->_fractional < 0) {
04540                 $this->subSecond(1);
04541                 $this->_fractional += $max;
04542             }
04543         }
04544 
04545         if ($this->_precision > strlen($this->_fractional)) {
04546             $this->_fractional = str_pad($this->_fractional, $this->_precision, '0', STR_PAD_LEFT);
04547         }
04548 
04549         return $this;
04550     }
04551 
04552 
04560     public function subMilliSecond($milli = null, $precision = null)
04561     {
04562         $this->addMilliSecond(0 - $milli, $precision);
04563         return $this;
04564     }
04565 
04574     public function compareMilliSecond($milli = null, $precision = null)
04575     {
04576         if ($milli === null) {
04577             list($milli, $time) = explode(" ", microtime());
04578             $milli = intval($milli);
04579         } else if (is_numeric($milli) === false) {
04580             require_once 'Zend/Date/Exception.php';
04581             throw new Zend_Date_Exception("invalid milli second ($milli) operand", 0, null, $milli);
04582         }
04583 
04584         if ($precision === null) {
04585             $precision = strlen($milli);
04586         } else if (!is_int($precision) || $precision < 1 || $precision > 9) {
04587             require_once 'Zend/Date/Exception.php';
04588             throw new Zend_Date_Exception("precision ($precision) must be a positive integer less than 10", 0, null, $precision);
04589         }
04590 
04591         if ($precision === 0) {
04592             require_once 'Zend/Date/Exception.php';
04593             throw new Zend_Date_Exception('precision is 0');
04594         }
04595 
04596         if ($precision != $this->_precision) {
04597             if ($precision > $this->_precision) {
04598                 $diff = $precision - $this->_precision;
04599                 $milli = (int) ($milli / (10 * $diff));
04600             } else {
04601                 $diff = $this->_precision - $precision;
04602                 $milli = (int) ($milli * (10 * $diff));
04603             }
04604         }
04605 
04606         $comp = $this->_fractional - $milli;
04607         if ($comp < 0) {
04608             return -1;
04609         } else if ($comp > 0) {
04610             return 1;
04611         }
04612         return 0;
04613     }
04614 
04622     public function getWeek($locale = null)
04623     {
04624         if (self::$_options['format_type'] == 'php') {
04625             $format = 'W';
04626         } else {
04627             $format = self::WEEK;
04628         }
04629 
04630         return $this->copyPart($format, $locale);
04631     }
04632 
04643     public function setWeek($week, $locale = null)
04644     {
04645         return $this->_calcvalue('set', $week, 'week', self::WEEK, $locale);
04646     }
04647 
04658     public function addWeek($week, $locale = null)
04659     {
04660         return $this->_calcvalue('add', $week, 'week', self::WEEK, $locale);
04661     }
04662 
04673     public function subWeek($week, $locale = null)
04674     {
04675         return $this->_calcvalue('sub', $week, 'week', self::WEEK, $locale);
04676     }
04677 
04688     public function compareWeek($week, $locale = null)
04689     {
04690         return $this->_calcvalue('cmp', $week, 'week', self::WEEK, $locale);
04691     }
04692 
04704     public function setLocale($locale = null)
04705     {
04706         try {
04707             $this->_locale = Zend_Locale::findLocale($locale);
04708         } catch (Zend_Locale_Exception $e) {
04709             require_once 'Zend/Date/Exception.php';
04710             throw new Zend_Date_Exception($e->getMessage(), 0, $e);
04711         }
04712 
04713         return $this;
04714     }
04715 
04721     public function getLocale()
04722     {
04723         return $this->_locale;
04724     }
04725 
04738     public static function isDate($date, $format = null, $locale = null)
04739     {
04740         if (!is_string($date) && !is_numeric($date) && !($date instanceof Zend_Date) &&
04741             !is_array($date)) {
04742             return false;
04743         }
04744 
04745         if (($format !== null) && ($format != 'ee') && ($format != 'ss') && ($format != 'GG') && ($format != 'MM') && ($format != 'EE') && ($format != 'TT')
04746             && (Zend_Locale::isLocale($format, null, false))) {
04747             $locale = $format;
04748             $format = null;
04749         }
04750 
04751         $locale = Zend_Locale::findLocale($locale);
04752 
04753         if ($format === null) {
04754             $format = Zend_Locale_Format::getDateFormat($locale);
04755         } else if ((self::$_options['format_type'] == 'php') && !defined($format)) {
04756             $format = Zend_Locale_Format::convertPhpToIsoFormat($format);
04757         }
04758 
04759         $format = self::_getLocalizedToken($format, $locale);
04760         if (!is_array($date)) {
04761             try {
04762                 $parsed = Zend_Locale_Format::getDate($date, array('locale' => $locale,
04763                                                       'date_format' => $format, 'format_type' => 'iso',
04764                                                       'fix_date' => false));
04765             } catch (Zend_Locale_Exception $e) {
04766                 // Date can not be parsed
04767                 return false;
04768             }
04769         } else {
04770             $parsed = $date;
04771         }
04772 
04773         if (((strpos($format, 'Y') !== false) or (strpos($format, 'y') !== false)) and
04774             (!isset($parsed['year']))) {
04775             // Year expected but not found
04776                 return false;
04777         }
04778 
04779         if ((strpos($format, 'M') !== false) and (!isset($parsed['month']))) {
04780             // Month expected but not found
04781             return false;
04782         }
04783 
04784         if ((strpos($format, 'd') !== false) and (!isset($parsed['day']))) {
04785             // Day expected but not found
04786             return false;
04787         }
04788 
04789         if (((strpos($format, 'H') !== false) or (strpos($format, 'h') !== false)) and
04790             (!isset($parsed['hour']))) {
04791             // Hour expected but not found
04792                 return false;
04793         }
04794 
04795         if ((strpos($format, 'm') !== false) and (!isset($parsed['minute']))) {
04796             // Minute expected but not found
04797             return false;
04798         }
04799 
04800         if ((strpos($format, 's') !== false) and (!isset($parsed['second']))) {
04801             // Second expected  but not found
04802             return false;
04803         }
04804 
04805         // Set not given dateparts
04806         if (isset($parsed['hour']) === false) {
04807             $parsed['hour'] = 12;
04808         }
04809 
04810         if (isset($parsed['minute']) === false) {
04811             $parsed['minute'] = 0;
04812         }
04813 
04814         if (isset($parsed['second']) === false) {
04815             $parsed['second'] = 0;
04816         }
04817 
04818         if (isset($parsed['month']) === false) {
04819             $parsed['month'] = 1;
04820         }
04821 
04822         if (isset($parsed['day']) === false) {
04823             $parsed['day'] = 1;
04824         }
04825 
04826         if (isset($parsed['year']) === false) {
04827             $parsed['year'] = 1970;
04828         }
04829 
04830         if (self::isYearLeapYear($parsed['year'])) {
04831             $parsed['year'] = 1972;
04832         } else {
04833             $parsed['year'] = 1971;
04834         }
04835 
04836         $date      = new self($parsed, null, $locale);
04837         $timestamp = $date->mktime($parsed['hour'], $parsed['minute'], $parsed['second'],
04838                                    $parsed['month'], $parsed['day'], $parsed['year']);
04839 
04840         if ($parsed['year'] != $date->date('Y', $timestamp)) {
04841             // Given year differs from parsed year
04842             return false;
04843         }
04844 
04845         if ($parsed['month'] != $date->date('n', $timestamp)) {
04846             // Given month differs from parsed month
04847             return false;
04848         }
04849 
04850         if ($parsed['day'] != $date->date('j', $timestamp)) {
04851             // Given day differs from parsed day
04852             return false;
04853         }
04854 
04855         if ($parsed['hour'] != $date->date('G', $timestamp)) {
04856             // Given hour differs from parsed hour
04857             return false;
04858         }
04859 
04860         if ($parsed['minute'] != $date->date('i', $timestamp)) {
04861             // Given minute differs from parsed minute
04862             return false;
04863         }
04864 
04865         if ($parsed['second'] != $date->date('s', $timestamp)) {
04866             // Given second differs from parsed second
04867             return false;
04868         }
04869 
04870         return true;
04871     }
04872 
04880     protected static function _getLocalizedToken($token, $locale)
04881     {
04882         switch($token) {
04883             case self::ISO_8601 :
04884                 return "yyyy-MM-ddThh:mm:ss";
04885                 break;
04886             case self::RFC_2822 :
04887                 return "EEE, dd MMM yyyy HH:mm:ss";
04888                 break;
04889             case self::DATES :
04890                 return Zend_Locale_Data::getContent($locale, 'date');
04891                 break;
04892             case self::DATE_FULL :
04893                 return Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'full'));
04894                 break;
04895             case self::DATE_LONG :
04896                 return Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'long'));
04897                 break;
04898             case self::DATE_MEDIUM :
04899                 return Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'medium'));
04900                 break;
04901             case self::DATE_SHORT :
04902                 return Zend_Locale_Data::getContent($locale, 'date', array('gregorian', 'short'));
04903                 break;
04904             case self::TIMES :
04905                 return Zend_Locale_Data::getContent($locale, 'time');
04906                 break;
04907             case self::TIME_FULL :
04908                 return Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'full'));
04909                 break;
04910             case self::TIME_LONG :
04911                 return Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'long'));
04912                 break;
04913             case self::TIME_MEDIUM :
04914                 return Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'medium'));
04915                 break;
04916             case self::TIME_SHORT :
04917                 return Zend_Locale_Data::getContent($locale, 'time', array('gregorian', 'short'));
04918                 break;
04919             case self::DATETIME :
04920                 return Zend_Locale_Data::getContent($locale, 'datetime');
04921                 break;
04922             case self::DATETIME_FULL :
04923                 return Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'full'));
04924                 break;
04925             case self::DATETIME_LONG :
04926                 return Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'long'));
04927                 break;
04928             case self::DATETIME_MEDIUM :
04929                 return Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'medium'));
04930                 break;
04931             case self::DATETIME_SHORT :
04932                 return Zend_Locale_Data::getContent($locale, 'datetime', array('gregorian', 'short'));
04933                 break;
04934             case self::ATOM :
04935             case self::RFC_3339 :
04936             case self::W3C :
04937                 return "yyyy-MM-DD HH:mm:ss";
04938                 break;
04939             case self::COOKIE :
04940             case self::RFC_850 :
04941                 return "EEEE, dd-MM-yyyy HH:mm:ss";
04942                 break;
04943             case self::RFC_822 :
04944             case self::RFC_1036 :
04945             case self::RFC_1123 :
04946             case self::RSS :
04947                 return "EEE, dd MM yyyy HH:mm:ss";
04948                 break;
04949         }
04950 
04951         return $token;
04952     }
04953 }
 All Data Structures Namespaces Files Functions Variables Enumerations