34 private $_unixTimestamp;
42 private $_timezone =
'UTC';
44 private $_syncronised = 0;
52 private static $_monthTable = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
57 private static $_yearTable = array(
58 1970 => 0, 1960 => -315619200, 1950 => -631152000,
59 1940 => -946771200, 1930 => -1262304000, 1920 => -1577923200,
60 1910 => -1893456000, 1900 => -2208988800, 1890 => -2524521600,
61 1880 => -2840140800, 1870 => -3155673600, 1860 => -3471292800,
62 1850 => -3786825600, 1840 => -4102444800, 1830 => -4417977600,
63 1820 => -4733596800, 1810 => -5049129600, 1800 => -5364662400,
64 1790 => -5680195200, 1780 => -5995814400, 1770 => -6311347200,
65 1760 => -6626966400, 1750 => -6942499200, 1740 => -7258118400,
66 1730 => -7573651200, 1720 => -7889270400, 1710 => -8204803200,
67 1700 => -8520336000, 1690 => -8835868800, 1680 => -9151488000,
68 1670 => -9467020800, 1660 => -9782640000, 1650 => -10098172800,
69 1640 => -10413792000, 1630 => -10729324800, 1620 => -11044944000,
70 1610 => -11360476800, 1600 => -11676096000);
81 $old = $this->_unixTimestamp;
83 if (is_numeric($timestamp)) {
84 $this->_unixTimestamp = $timestamp;
85 }
else if ($timestamp ===
null) {
86 $this->_unixTimestamp =
time();
88 #require_once 'Zend/Date/Exception.php'; 89 throw new Zend_Date_Exception(
'\'' . $timestamp .
'\' is not a valid UNIX timestamp
', 0, null, $timestamp); 102 protected function getUnixTimestamp() 104 if ($this->_unixTimestamp === intval($this->_unixTimestamp)) { 105 return (int) $this->_unixTimestamp; 107 return (string) $this->_unixTimestamp; 119 protected function _getTime($sync = null) 121 if ($sync !== null) { 122 $this->_syncronised = round($sync); 124 return (time() + $this->_syncronised); 146 protected function mktime($hour, $minute, $second, $month, $day, $year, $gmt = false) 148 // complete date but in 32bit timestamp - use PHP internal 149 if ((1901 < $year) and ($year < 2038)) { 151 $oldzone = @date_default_timezone_get(); 152 // Timezone also includes DST settings, therefor substracting the GMT offset is not enough 153 // We have to set the correct timezone to get the right value 154 if (($this->_timezone != $oldzone) and ($gmt === false)) { 155 date_default_timezone_set($this->_timezone); 157 $result = ($gmt) ? @gmmktime($hour, $minute, $second, $month, $day, $year) 158 : @mktime($hour, $minute, $second, $month, $day, $year); 159 date_default_timezone_set($oldzone); 165 $second += $this->_offset; 168 if (isset(self::$_cache)) { 169 $id = strtr('Zend_DateObject_mkTime_
' . $this->_offset . '_
' . $year.$month.$day.'_
'.$hour.$minute.$second . '_
'.(int)$gmt, '-
','_
'); 170 if ($result = self::$_cache->load($id)) { 171 return unserialize($result); 177 $month = intval($month); 178 $year = intval($year); 180 // correct months > 12 and months < 1 182 $overlap = floor($month / 12); 184 $month -= $overlap * 12; 186 $overlap = ceil((1 - $month) / 12); 188 $month += $overlap * 12; 194 // Date is after UNIX epoch 195 // go through leapyears 196 // add months from latest given year 197 for ($count = 1970; $count <= $year; $count++) { 199 $leapyear = self::isYearLeapYear($count); 200 if ($count < $year) { 203 if ($leapyear === true) { 209 for ($mcount = 0; $mcount < ($month - 1); $mcount++) { 210 $date += self::$_monthTable[$mcount]; 211 if (($leapyear === true) and ($mcount == 1)) { 220 $date = (($date * 86400) + ($hour * 3600) + ($minute * 60) + $second); 223 // Date is before UNIX epoch 224 // go through leapyears 225 // add months from latest given year 226 for ($count = 1969; $count >= $year; $count--) { 228 $leapyear = self::isYearLeapYear($count); 232 if ($leapyear === true) 236 for ($mcount = 11; $mcount > ($month - 1); $mcount--) { 237 $date += self::$_monthTable[$mcount]; 238 if (($leapyear === true) and ($mcount == 2)) { 246 $date += (self::$_monthTable[$month - 1] - $day); 247 $date = -(($date * 86400) + (86400 - (($hour * 3600) + ($minute * 60) + $second))); 249 // gregorian correction for 5.Oct.1582 250 if ($date < -12220185600) { 252 } else if ($date < -12219321600) { 253 $date = -12219321600; 257 if (isset(self::$_cache)) { 258 if (self::$_cacheTags) { 259 self::$_cache->save( serialize($date), $id, array('Zend_Date')); 261 self::$_cache->save( serialize($date), $id); 274 protected static function isYearLeapYear($year) 276 // all leapyears can be divided through 4 277 if (($year % 4) != 0) { 281 // all leapyears can be divided through 400 282 if ($year % 400 == 0) { 284 } else if (($year > 1582) and ($year % 100 == 0)) { 301 protected function date($format, $timestamp = null, $gmt = false) 303 $oldzone = @date_default_timezone_get(); 304 if ($this->_timezone != $oldzone) { 305 date_default_timezone_set($this->_timezone); 308 if ($timestamp === null) { 309 $result = ($gmt) ? @gmdate($format) : @date($format); 310 date_default_timezone_set($oldzone); 314 if (abs($timestamp) <= 0x7FFFFFFF) { 316 // "o" will sometimes resolve to the previous year (see 317 // http://php.net/date ; it's part of the ISO 8601
323 date_default_timezone_set($oldzone);
328 $origstamp = $timestamp;
329 if (isset(self::$_cache)) {
330 $idstamp = strtr(
'Zend_DateObject_date_' . $this->_offset .
'_'. $timestamp .
'_'.(
int)$gmt,
'-',
'_');
331 if ($result2 = self::$_cache->load($idstamp)) {
332 $timestamp = unserialize($result2);
338 if (empty($gmt) and empty($jump)) {
339 $tempstamp = $timestamp;
340 if ($tempstamp > 0) {
341 while (abs($tempstamp) > 0x7FFFFFFF) {
342 $tempstamp -= (86400 * 23376);
345 $dst =
date(
"I", $tempstamp);
350 $temp =
date(
'Z', $tempstamp);
354 if (isset(self::$_cache)) {
355 if (self::$_cacheTags) {
356 self::$_cache->save( serialize($timestamp), $idstamp, array(
'Zend_Date'));
358 self::$_cache->save( serialize($timestamp), $idstamp);
363 if (($timestamp < 0) and ($gmt !==
true)) {
364 $timestamp -= $this->_offset;
367 date_default_timezone_set($oldzone);
372 for (
$i = 0;
$i < $length;
$i++) {
376 $output .= (($date[
'mday'] < 10) ?
'0' . $date[
'mday'] : $date[
'mday']);
380 $output .=
date(
'D', 86400 * (3 + self::dayOfWeek($date[
'year'], $date[
'mon'], $date[
'mday'])));
388 $output .=
date(
'l', 86400 * (3 + self::dayOfWeek($date[
'year'], $date[
'mon'], $date[
'mday'])));
400 if (($date[
'mday'] % 10) == 1) {
402 }
else if ((($date[
'mday'] % 10) == 2) and ($date[
'mday'] != 12)) {
404 }
else if (($date[
'mday'] % 10) == 3) {
432 $output .= (($date[
'mon'] < 10) ?
'0' . $date[
'mon'] : $date[
'mon']);
444 $output .= self::$_monthTable[$date[
'mon'] - 1];
454 $week = $this->
weekNumber($date[
'year'], $date[
'mon'], $date[
'mday']);
455 if (($week > 50) and ($date[
'mon'] == 1)) {
456 $output .= ($date[
'year'] - 1);
467 $output .= substr($date[
'year'], strlen($date[
'year']) - 2, 2);
473 $output .= (($date[
'hours'] >= 12) ?
'pm' :
'am');
477 $output .= (($date[
'hours'] >= 12) ?
'PM' :
'AM');
481 $dayseconds = ($date[
'hours'] * 3600) + ($date[
'minutes'] * 60) + $date[
'seconds'];
485 $output .= (int) (($dayseconds % 86400) / 86.4);
489 if ($date[
'hours'] > 12) {
490 $hour = $date[
'hours'] - 12;
492 if ($date[
'hours'] == 0) {
495 $hour = $date[
'hours'];
506 if ($date[
'hours'] > 12) {
507 $hour = $date[
'hours'] - 12;
509 if ($date[
'hours'] == 0) {
512 $hour = $date[
'hours'];
515 $output .= (($hour < 10) ?
'0'.$hour : $hour);
519 $output .= (($date[
'hours'] < 10) ?
'0' . $date[
'hours'] : $date[
'hours']);
523 $output .= (($date[
'minutes'] < 10) ?
'0' . $date[
'minutes'] : $date[
'minutes']);
527 $output .= (($date[
'seconds'] < 10) ?
'0' . $date[
'seconds'] : $date[
'seconds']);
535 $date[
'mon'], $date[
'mday'], 2000));
538 $date[
'mon'], $date[
'mday'], 2000));
545 $date[
'mon'], $date[
'mday'], 2000));
548 $date[
'mon'], $date[
'mday'], 2000));
554 $output .= sprintf(
'%s%04d', ($gmtstr <= 0) ?
'+' :
'-', abs($gmtstr) / 36);
559 $gmtstr = sprintf(
'%s%04d', ($gmtstr <= 0) ?
'+' :
'-', abs($gmtstr) / 36);
560 $output =
$output . substr($gmtstr, 0, 3) .
':' . substr($gmtstr, 3);
566 $date[
'mon'], $date[
'mday'], 2000));
569 $date[
'mon'], $date[
'mday'], 2000));
581 $difference = sprintf(
'%s%04d', ($difference <= 0) ?
'+' :
'-', abs($difference) / 36);
582 $difference = substr($difference, 0, 3) .
':' . substr($difference, 3);
584 . (($date[
'mon'] < 10) ?
'0' . $date[
'mon'] : $date[
'mon']) .
'-' 585 . (($date[
'mday'] < 10) ?
'0' . $date[
'mday'] : $date[
'mday']) .
'T' 586 . (($date[
'hours'] < 10) ?
'0' . $date[
'hours'] : $date[
'hours']) .
':' 587 . (($date[
'minutes'] < 10) ?
'0' . $date[
'minutes'] : $date[
'minutes']) .
':' 588 . (($date[
'seconds'] < 10) ?
'0' . $date[
'seconds'] : $date[
'seconds'])
594 $difference = sprintf(
'%s%04d', ($difference <= 0) ?
'+' :
'-', abs($difference) / 36);
595 $output .=
gmdate(
'D', 86400 * (3 + self::dayOfWeek($date[
'year'], $date[
'mon'], $date[
'mday']))) .
', ' 596 . (($date[
'mday'] < 10) ?
'0' . $date[
'mday'] : $date[
'mday']) .
' ' 597 .
date(
'M',
mktime(0, 0, 0, $date[
'mon'], 2, 1971)) .
' ' 598 . $date[
'year'] .
' ' 599 . (($date[
'hours'] < 10) ?
'0' . $date[
'hours'] : $date[
'hours']) .
':' 600 . (($date[
'minutes'] < 10) ?
'0' . $date[
'minutes'] : $date[
'minutes']) .
':' 601 . (($date[
'seconds'] < 10) ?
'0' . $date[
'seconds'] : $date[
'seconds']) .
' ' 636 protected static function dayOfWeek($year, $month, $day)
638 if ((1901 < $year) and ($year < 2038)) {
639 return (
int)
date(
'w',
mktime(0, 0, 0, $month, $day, $year));
644 if (($year < 1582) or (($year == 1582) and (($month < 10) or (($month == 10) && ($day < 15))))) {
655 $day = floor((13 * $month - 1) / 5) + $day + ($year % 100) + floor(($year % 100) / 4);
656 $day += floor(($year / 100) / 4) - 2 * floor($year / 100) + 77 + $correction;
658 return (
int) ($day - 7 * floor($day / 7));
678 if (!is_numeric($timestamp)) {
683 if (abs($timestamp) <= 0x7FFFFFFF) {
684 return @getdate((
int) $timestamp);
687 if (isset(self::$_cache)) {
688 $id = strtr(
'Zend_DateObject_getDateParts_' . $timestamp.
'_'.(
int)$fast,
'-',
'_');
694 $otimestamp = $timestamp;
698 if ($timestamp < -12219321600) {
699 $timestamp -= 864000;
703 if ($timestamp < 0) {
708 foreach(self::$_yearTable as $year => $seconds) {
709 if ($timestamp >= $seconds) {
727 $timestamp += 31536000;
729 if ($leapyear ===
true) {
733 if ($timestamp >= 0) {
737 }
while ($timestamp < 0);
739 $secondsPerYear = 86400 * ($leapyear ? 366 : 365) + $day;
743 for (
$i = 12; --
$i >= 0;) {
746 $timestamp += self::$_monthTable[
$i] * 86400;
747 if (($leapyear ===
true) and (
$i == 1)) {
751 if ($timestamp >= 0) {
753 $numday = self::$_monthTable[
$i];
754 if (($leapyear ===
true) and (
$i == 1)) {
762 $numberdays = $numday + ceil(($timestamp + 1) / 86400);
764 $timestamp += ($numday - $numberdays + 1) * 86400;
765 $hours = floor($timestamp / 3600);
769 for (
$i = 1970;;
$i++) {
772 $timestamp -= 31536000;
774 if ($leapyear ===
true) {
778 if ($timestamp < 0) {
784 $secondsPerYear = $day;
788 for (
$i = 0;
$i <= 11;
$i++) {
790 $timestamp -= self::$_monthTable[
$i] * 86400;
792 if (($leapyear ===
true) and (
$i == 1)) {
796 if ($timestamp < 0) {
798 $numday = self::$_monthTable[
$i];
799 if (($leapyear ===
true) and (
$i == 1)) {
807 $numberdays = ceil(($timestamp + 1) / 86400);
808 $timestamp = $timestamp - ($numberdays - 1) * 86400;
809 $hours = floor($timestamp / 3600);
812 $timestamp -= $hours * 3600;
815 $minutes = floor($timestamp / 60);
816 $seconds = $timestamp - $minutes * 60;
818 if ($fast ===
true) {
820 'seconds' => $seconds,
821 'minutes' => $minutes,
823 'mday' => $numberdays,
826 'yday' => floor($secondsPerYear / 86400),
832 'seconds' => $seconds,
833 'minutes' => $minutes,
835 'mday' => $numberdays,
836 'wday' => $dayofweek,
839 'yday' => floor($secondsPerYear / 86400),
840 'weekday' =>
gmdate(
'l', 86400 * (3 + $dayofweek)),
841 'month' =>
gmdate(
'F',
mktime(0, 0, 0, $month, 1, 1971)),
846 if (isset(self::$_cache)) {
847 if (self::$_cacheTags) {
848 self::$_cache->save( serialize($array),
$id, array(
'Zend_Date'));
850 self::$_cache->save( serialize($array),
$id);
869 if ((1901 < $year) and ($year < 2038)) {
870 return (
int)
date(
'W',
mktime(0, 0, 0, $month, $day, $year));
875 if (($month == 1) and (($firstday < 1) or ($firstday > 4)) and ($day < 4)) {
880 }
else if (($month == 12) and ((self::dayOfWeek($year + 1, 1, 1) < 5) and
881 (self::dayOfWeek($year + 1, 1, 1) > 0))) {
885 return intval (((self::dayOfWeek($year, 1, 1) < 5) and (self::dayOfWeek($year, 1, 1) > 0)) +
886 4 * ($month - 1) + (2 * ($month - 1) + ($day - 1) + $firstday - $dayofweek + 6) * 36 / 256);
896 private function _range($a, $b) {
913 protected function calcSun($location, $horizon, $rise =
false)
916 if (abs($this->_unixTimestamp) <= 0x7FFFFFFF) {
917 if ($rise ===
false) {
918 return date_sunset($this->_unixTimestamp, SUNFUNCS_RET_TIMESTAMP, $location[
'latitude'],
919 $location[
'longitude'], 90 + $horizon, $this->
getGmtOffset() / 3600);
921 return date_sunrise($this->_unixTimestamp, SUNFUNCS_RET_TIMESTAMP, $location[
'latitude'],
922 $location[
'longitude'], 90 + $horizon, $this->
getGmtOffset() / 3600);
927 $quarterCircle = 0.5 * M_PI;
929 $threeQuarterCircle = 1.5 * M_PI;
930 $fullCircle = 2 * M_PI;
933 $radLatitude = $location[
'latitude'] * $halfCircle / 180;
934 $radLongitude = $location[
'longitude'] * $halfCircle / 180;
937 $tmpRise = $rise ? $quarterCircle : $threeQuarterCircle;
938 $radDay = $this->
date(
'z',$this->_unixTimestamp) + ($tmpRise - $radLongitude) / $fullCircle;
941 $solAnomoly = $radDay * 0.017202 - 0.0574039;
942 $solLongitude = $solAnomoly + 0.0334405 * sin($solAnomoly);
943 $solLongitude += 4.93289 + 3.49066E-4 * sin(2 * $solAnomoly);
946 $solLongitude = $this->_range($solLongitude, $fullCircle);
948 if (($solLongitude / $quarterCircle) - intval($solLongitude / $quarterCircle) == 0) {
949 $solLongitude += 4.84814E-6;
953 $solAscension = sin($solLongitude) / cos($solLongitude);
954 $solAscension = atan2(0.91746 * $solAscension, 1);
957 if ($solLongitude > $threeQuarterCircle) {
958 $solAscension += $fullCircle;
959 }
else if ($solLongitude > $quarterCircle) {
960 $solAscension += $halfCircle;
964 $solDeclination = 0.39782 * sin($solLongitude);
965 $solDeclination /= sqrt(-$solDeclination * $solDeclination + 1);
966 $solDeclination = atan2($solDeclination, 1);
968 $solHorizon = $horizon - sin($solDeclination) * sin($radLatitude);
969 $solHorizon /= cos($solDeclination) * cos($radLatitude);
972 if (abs($solHorizon) > 1) {
976 $solHorizon /= sqrt(-$solHorizon * $solHorizon + 1);
977 $solHorizon = $quarterCircle - atan2($solHorizon, 1);
980 $solHorizon = $fullCircle - $solHorizon;
984 $localTime = $solHorizon + $solAscension - 0.0172028 * $radDay - 1.73364;
985 $universalTime = $localTime - $radLongitude;
988 $universalTime = $this->_range($universalTime, $fullCircle);
991 $universalTime *= 24 / $fullCircle;
994 $hour = intval($universalTime);
995 $universalTime = ($universalTime - $hour) * 60;
996 $min = intval($universalTime);
997 $universalTime = ($universalTime - $min) * 60;
998 $sec = intval($universalTime);
1000 return $this->
mktime($hour, $min, $sec, $this->
date(
'm', $this->_unixTimestamp),
1001 $this->
date(
'j', $this->_unixTimestamp), $this->
date(
'Y', $this->_unixTimestamp),
1016 $oldzone = @date_default_timezone_get();
1017 if ($zone ===
null) {
1023 if (!@timezone_open($zone)) {
1024 #require_once 'Zend/Date/Exception.php'; 1025 throw new Zend_Date_Exception(
"timezone ($zone) is not a known timezone", 0,
null, $zone);
1029 $result = @date_default_timezone_set($zone);
1031 $this->_offset =
mktime(0, 0, 0, 1, 2, 1970) - gmmktime(0, 0, 0, 1, 2, 1970);
1032 $this->_timezone = $zone;
1034 date_default_timezone_set($oldzone);
1036 if (($zone ==
'UTC') or ($zone ==
'GMT')) {
1037 $this->_dst =
false;
1053 return $this->_timezone;
1066 $zone = @date_default_timezone_get();
1067 $result = @date_default_timezone_set($this->_timezone);
1069 $offset = $this->
mktime($date[
'hours'], $date[
'minutes'], $date[
'seconds'],
1070 $date[
'mon'], $date[
'mday'], $date[
'year'],
false)
1071 - $this->
mktime($date[
'hours'], $date[
'minutes'], $date[
'seconds'],
1072 $date[
'mon'], $date[
'mday'], $date[
'year'],
true);
1074 date_default_timezone_set($zone);
1086 $backend = self::$_cache->getBackend();
1088 $cacheOptions = $backend->getCapabilities();
1089 self::$_cacheTags = $cacheOptions[
'tags'];
1091 self::$_cacheTags =
false;
calcSun($location, $horizon, $rise=false)
date($format, $timestamp=null, $gmt=false)
mktime($hour, $minute, $second, $month, $day, $year, $gmt=false)
static _getTagSupportForCache()
setUnixTimestamp($timestamp=null)
static isYearLeapYear($year)
getDateParts($timestamp=null, $fast=null)
weekNumber($year, $month, $day)
static dayOfWeek($year, $month, $day)