dateobject.php
来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 1,013 行 · 第 1/3 页
PHP
1,013 行
// iterate the max last 10 years
do {
--$i;
$day = $timestamp;
$timestamp += 31536000;
$leapyear = self::isYearLeapYear($i);
if ($leapyear === true) {
$timestamp += 86400;
}
if ($timestamp >= 0) {
$year = $i;
break;
}
} while ($timestamp < 0);
$secondsPerYear = 86400 * ($leapyear ? 366 : 365) + $day;
$timestamp = $day;
// iterate through months
for ($i = 12; --$i >= 0;) {
$day = $timestamp;
$timestamp += self::$_monthTable[$i] * 86400;
if (($leapyear === true) and ($i == 1)) {
$timestamp += 86400;
}
if ($timestamp >= 0) {
$month = $i;
$numday = self::$_monthTable[$i];
if (($leapyear === true) and ($i == 1)) {
++$numday;
}
break;
}
}
$timestamp = $day;
$numberdays = $numday + ceil(($timestamp + 1) / 86400);
$timestamp += ($numday - $numberdays + 1) * 86400;
$hours = floor($timestamp / 3600);
} else {
// iterate through years
for ($i = 1970;;$i++) {
$day = $timestamp;
$timestamp -= 31536000;
$leapyear = self::isYearLeapYear($i);
if ($leapyear === true) {
$timestamp -= 86400;
}
if ($timestamp < 0) {
$year = $i;
break;
}
}
$secondsPerYear = $day;
$timestamp = $day;
// iterate through months
for ($i = 0; $i <= 11; $i++) {
$day = $timestamp;
$timestamp -= self::$_monthTable[$i] * 86400;
if (($leapyear === true) and ($i == 1)) {
$timestamp -= 86400;
}
if ($timestamp < 0) {
$month = $i;
$numday = self::$_monthTable[$i];
if (($leapyear === true) and ($i == 1)) {
++$numday;
}
break;
}
}
$timestamp = $day;
$numberdays = ceil(($timestamp + 1) / 86400);
$timestamp = $timestamp - ($numberdays - 1) * 86400;
$hours = floor($timestamp / 3600);
}
$timestamp -= $hours * 3600;
$month += 1;
$minutes = floor($timestamp / 60);
$seconds = $timestamp - $minutes * 60;
if ($fast === true) {
return array(
'seconds' => $seconds,
'minutes' => $minutes,
'hours' => $hours,
'mday' => $numberdays,
'mon' => $month,
'year' => $year,
'yday' => floor($secondsPerYear / 86400),
);
}
$dayofweek = self::dayOfWeek($year, $month, $numberdays);
return array(
'seconds' => $seconds,
'minutes' => $minutes,
'hours' => $hours,
'mday' => $numberdays,
'wday' => $dayofweek,
'mon' => $month,
'year' => $year,
'yday' => floor($secondsPerYear / 86400),
'weekday' => gmdate('l', 86400 * (3 + $dayofweek)),
'month' => gmdate('F', mktime(0, 0, 0, $month, 1, 1971)),
0 => $otimestamp
);
}
/**
* Internal getWeekNumber function for handling 64bit timestamps
*
* Returns the ISO 8601 week number of a given date
*
* @param integer $year
* @param integer $month
* @param integer $day
* @return integer
*/
protected function weekNumber($year, $month, $day)
{
if ((1901 < $year) and ($year < 2038)) {
return (int) date('W', mktime(0, 0, 0, $month, $day, $year));
}
$dayofweek = self::dayOfWeek($year, $month, $day);
$firstday = self::dayOfWeek($year, 1, 1);
if (($month == 1) and (($firstday < 1) or ($firstday > 4)) and ($day < 4)) {
$firstday = self::dayOfWeek($year - 1, 1, 1);
$month = 12;
$day = 31;
} else if (($month == 12) and ((self::dayOfWeek($year + 1, 1, 1) < 5) and
(self::dayOfWeek($year + 1, 1, 1) > 0))) {
return 1;
}
return intval (((self::dayOfWeek($year, 1, 1) < 5) and (self::dayOfWeek($year, 1, 1) > 0)) +
4 * ($month - 1) + (2 * ($month - 1) + ($day - 1) + $firstday - $dayofweek + 6) * 36 / 256);
}
/**
* Internal _range function
* Sets the value $a to be in the range of [0, $b]
*
* @param float $a - value to correct
* @param float $b - maximum range to set
*/
private function _range($a, $b) {
while ($a < 0) {
$a += $b;
}
while ($a >= $b) {
$a -= $b;
}
return $a;
}
/**
* Calculates the sunrise or sunset based on a location
*
* @param array $location Location for calculation MUST include 'latitude', 'longitude', 'horizon'
* @param bool $horizon true: sunrise; false: sunset
* @return mixed - false: midnight sun, integer:
*/
protected function calcSun($location, $horizon, $rise = false)
{
// timestamp within 32bit
if (abs($this->_unixTimestamp) <= 0x7FFFFFFF) {
if ($rise === false) {
return date_sunset($this->_unixTimestamp, SUNFUNCS_RET_TIMESTAMP, $location['latitude'],
$location['longitude'], 90 + $horizon, $this->_offset / 3600);
}
return date_sunrise($this->_unixTimestamp, SUNFUNCS_RET_TIMESTAMP, $location['latitude'],
$location['longitude'], 90 + $horizon, $this->_offset / 3600);
}
// self calculation - timestamp bigger than 32bit
// fix circle values
$quarterCircle = 0.5 * M_PI;
$halfCircle = M_PI;
$threeQuarterCircle = 1.5 * M_PI;
$fullCircle = 2 * M_PI;
// radiant conversion for coordinates
$radLatitude = $location['latitude'] * $halfCircle / 180;
$radLongitude = $location['longitude'] * $halfCircle / 180;
// get solar coordinates
$tmpRise = $rise ? $quarterCircle : $threeQuarterCircle;
$radDay = $this->date('z',$this->_unixTimestamp) + ($tmpRise - $radLongitude) / $fullCircle;
// solar anomoly and longitude
$solAnomoly = $radDay * 0.017202 - 0.0574039;
$solLongitude = $solAnomoly + 0.0334405 * sin($solAnomoly);
$solLongitude += 4.93289 + 3.49066E-4 * sin(2 * $solAnomoly);
// get quadrant
$solLongitude = $this->_range($solLongitude, $fullCircle);
if (($solLongitude / $quarterCircle) - intval($solLongitude / $quarterCircle) == 0) {
$solLongitude += 4.84814E-6;
}
// solar ascension
$solAscension = sin($solLongitude) / cos($solLongitude);
$solAscension = atan2(0.91746 * $solAscension, 1);
// adjust quadrant
if ($solLongitude > $threeQuarterCircle) {
$solAscension += $fullCircle;
} else if ($solLongitude > $quarterCircle) {
$solAscension += $halfCircle;
}
// solar declination
$solDeclination = 0.39782 * sin($solLongitude);
$solDeclination /= sqrt(-$solDeclination * $solDeclination + 1);
$solDeclination = atan2($solDeclination, 1);
$solHorizon = $horizon - sin($solDeclination) * sin($radLatitude);
$solHorizon /= cos($solDeclination) * cos($radLatitude);
// midnight sun, always night
if (abs($solHorizon) > 1) {
return false;
}
$solHorizon /= sqrt(-$solHorizon * $solHorizon + 1);
$solHorizon = $quarterCircle - atan2($solHorizon, 1);
if ($rise) {
$solHorizon = $fullCircle - $solHorizon;
}
// time calculation
$localTime = $solHorizon + $solAscension - 0.0172028 * $radDay - 1.73364;
$universalTime = $localTime - $radLongitude;
// determinate quadrant
$universalTime = $this->_range($universalTime, $fullCircle);
// radiant to hours
$universalTime *= 24 / $fullCircle;
// convert to time
$hour = intval($universalTime);
$universalTime = ($universalTime - $hour) * 60;
$min = intval($universalTime);
$universalTime = ($universalTime - $min) * 60;
$sec = intval($universalTime);
return $this->mktime($hour, $min, $sec, $this->date('m', $this->_unixTimestamp),
$this->date('j', $this->_unixTimestamp), $this->date('Y', $this->_unixTimestamp),
-1, true);
}
/**
* Sets a new timezone for calculation of $this object's gmt offset.
* For a list of supported timezones look here: http://php.net/timezones
* If no timezone can be detected or the given timezone is wrong UTC will be set.
*
* @param string $zone OPTIONAL timezone for date calculation; defaults to date_default_timezone_get()
* @return string actual set timezone string
* @throws Zend_Date_Exception
*/
public function setTimezone($zone = null)
{
$oldzone = @date_default_timezone_get();
if ($zone === null) {
$zone = $oldzone;
}
// throw an error on false input, but only if the new date extension is avaiable
if (function_exists('timezone_open')) {
if (!@timezone_open($zone)) {
throw new Zend_Date_Exception("timezone ($zone) is not a known timezone", $zone);
}
}
// this can generate an error if the date extension is not avaiable and a false timezone is given
$result = date_default_timezone_set($zone);
if ($result === true) {
$this->_offset = mktime(0, 0, 0, 1, 2, 1970) - gmmktime(0, 0, 0, 1, 2, 1970);
$this->_timezone = $zone;
}
date_default_timezone_set($oldzone);
return $result;
}
/**
* Return the timezone of $this object.
* The timezone is initially set when the object is instantiated.
*
* @return string actual set timezone string
*/
public function getTimezone()
{
return $this->_timezone;
}
/**
* Return the offset to GMT of $this object's timezone.
* The offset to GMT is initially set when the object is instantiated using the currently,
* in effect, default timezone for PHP functions.
*
* @return integer seconds difference between GMT timezone and timezone when object was instantiated
*/
public function getGmtOffset()
{
return $this->_offset;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?