dateobject.php
来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 1,013 行 · 第 1/3 页
PHP
1,013 行
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Date
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @version $Id: DateObject.php 3877 2007-03-12 21:24:41Z thomas $
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* Include needed Date classes
*/
require_once 'Zend/Date/Exception.php';
/**
* @category Zend
* @package Zend_Date
* @subpackage Zend_Date_DateObject
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Date_DateObject {
/**
* UNIX Timestamp
*/
private $_unixTimestamp;
/**
* active timezone
*/
private $_timezone = 'UTC';
private $_offset = 0;
private $_syncronised = 0;
/**
* Table of Monthdays
*/
private static $_monthTable = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
/**
* Table of Years
*/
private static $_yearTable = array(
1970 => 0, 1960 => -315619200, 1950 => -631152000,
1940 => -946771200, 1930 => -1262304000, 1920 => -1577923200,
1910 => -1893456000, 1900 => -2208988800, 1890 => -2524521600,
1880 => -2840140800, 1870 => -3155673600, 1860 => -3471292800,
1850 => -3786825600, 1840 => -4102444800, 1830 => -4417977600,
1820 => -4733596800, 1810 => -5049129600, 1800 => -5364662400,
1790 => -5680195200, 1780 => -5995814400, 1770 => -6311347200,
1760 => -6626966400, 1750 => -6942499200, 1740 => -7258118400,
1730 => -7573651200, 1720 => -7889270400, 1710 => -8204803200,
1700 => -8520336000, 1690 => -8835868800, 1680 => -9151488000,
1670 => -9467020800, 1660 => -9782640000, 1650 => -10098172800,
1640 => -10413792000, 1630 => -10729324800, 1620 => -11044944000,
1610 => -11360476800, 1600 => -11676096000);
/**
* Set this object to have a new UNIX timestamp.
*
* @param string|integer $timestamp OPTIONAL timestamp; defaults to local time using time()
* @return string|integer old timestamp
* @throws Zend_Date_Exception
*/
protected function setUnixTimestamp($timestamp = null)
{
$old = $this->_unixTimestamp;
if (is_numeric($timestamp)) {
$this->_unixTimestamp = $timestamp;
} else if ($timestamp === null) {
$this->_unixTimestamp = time();
} else {
throw new Zend_Date_Exception('\'' . $timestamp . '\' is not a valid UNIX timestamp', $timestamp);
}
return $old;
}
/**
* Returns this object's UNIX timestamp
* A timestamp greater then the integer range will be returned as string
* This function does not return the timestamp as object. Use copy() instead.
*
* @return integer|string timestamp
*/
protected function getUnixTimestamp()
{
if ($this->_unixTimestamp === intval($this->_unixTimestamp)) {
return (int) $this->_unixTimestamp;
} else {
return (string) $this->_unixTimestamp;
}
}
/**
* Internal function.
* Returns time(). This method exists to allow unit tests to work-around methods that might otherwise
* be hard-coded to use time(). For example, this makes it possible to test isYesterday() in Date.php.
*
* @param integer $sync OPTIONAL time syncronisation value
* @return integer timestamp
*/
protected function _getTime($sync = null)
{
if ($sync !== null) {
$this->_syncronised = round($sync);
}
return (time() + $this->_syncronised);
}
/**
* Internal mktime function used by Zend_Date.
* The timestamp returned by mktime() can exceed the precision of traditional UNIX timestamps,
* by allowing PHP to auto-convert to using a float value.
*
* Returns a timestamp relative to 1970/01/01 00:00:00 GMT/UTC.
* DST (Summer/Winter) is depriciated since php 5.1.0.
* Year has to be 4 digits otherwise it would be recognised as
* year 70 AD instead of 1970 AD as expected !!
*
* @param integer $hour
* @param integer $minute
* @param integer $second
* @param integer $month
* @param integer $day
* @param integer $year
* @param boolean $gmt OPTIONAL true = other arguments are for UTC time, false = arguments are for local time/date
* @return integer|float timestamp (number of seconds elapsed relative to 1970/01/01 00:00:00 GMT/UTC)
*/
protected function mktime($hour, $minute, $second, $month, $day, $year, $gmt = false)
{
// complete date but in 32bit timestamp - use PHP internal
if ((1901 < $year) and ($year < 2038)) {
$oldzone = @date_default_timezone_get();
// Timezone also includes DST settings, therefor substracting the GMT offset is not enough
// We have to set the correct timezone to get the right value
if (($this->_timezone != $oldzone) and ($gmt === false)) {
$second -= $this->_offset;
date_default_timezone_set($this->_timezone);
}
$result = ($gmt) ? @gmmktime($hour, $minute, $second, $month, $day, $year)
: @mktime($hour, $minute, $second, $month, $day, $year);
date_default_timezone_set($oldzone);
return $result;
}
// after here we are handling 64bit timestamps
// get difference from local to gmt
$difference = ($gmt) ? 0
: $this->_offset;
// date to integer
$day = intval($day);
$month = intval($month);
$year = intval($year);
// correct months > 12 and months < 1
if ($month > 12) {
$overlap = floor($month / 12);
$year += $overlap;
$month -= $overlap * 12;
} else {
$overlap = ceil((1 - $month) / 12);
$year -= $overlap;
$month += $overlap * 12;
}
$date = 0;
if ($year >= 1970) {
// Date is after UNIX epoch
// go through leapyears
// add months from letest given year
for ($count = 1970; $count <= $year; $count++) {
$leapyear = self::isYearLeapYear($count);
if ($count < $year) {
$date += 365;
if ($leapyear === true) {
$date++;
}
} else {
for ($mcount = 0; $mcount < ($month - 1); $mcount++) {
$date += self::$_monthTable[$mcount];
if (($leapyear === true) and ($mcount == 1)) {
$date++;
}
}
}
}
$date += $day - 1;
return (($date * 86400) + ($hour * 3600) + ($minute * 60) + $second + $difference);
} else {
// Date is before UNIX epoch
// go through leapyears
// add months from latest given year
for ($count = 1969; $count >= $year; $count--) {
$leapyear = self::isYearLeapYear($count);
if ($count > $year)
{
$date += 365;
if ($leapyear === true)
$date++;
} else {
for ($mcount = 11; $mcount > ($month - 1); $mcount--) {
$date += self::$_monthTable[$mcount];
if (($leapyear === true) and ($mcount == 1)) {
$date++;
}
}
}
}
$date += (self::$_monthTable[$month - 1] - $day);
$date = -(($date * 86400) + (86400 - (($hour * 3600) + ($minute * 60) + $second)) + $difference);
// gregorian correction for 5.Oct.1582
if ($date < -12220185600) {
$date += 864000;
} else if ($date < -12219321600) {
$date = -12219321600;
}
return $date;
}
}
/**
* Returns true, if given $year is a leap year.
*
* @param integer $year
* @return boolean true, if year is leap year
*/
protected static function isYearLeapYear($year)
{
// all leapyears can be divided through 4
if (($year % 4) != 0) {
return false;
}
// all leapyears can be divided through 400
if ($year % 400 == 0) {
return true;
} else if (($year > 1582) and ($year % 100 == 0)) {
return false;
}
return true;
}
/**
* Internal mktime function used by Zend_Date for handling 64bit timestamps.
*
* Returns a formatted date for a given timestamp.
*
* @param string $format format for output
* @param mixed $timestamp
* @param boolean $gmt OPTIONAL true = other arguments are for UTC time, false = arguments are for local time/date
* @return string
*/
protected function date($format, $timestamp = null, $gmt = false)
{
if ($timestamp === null) {
$oldzone = @date_default_timezone_get();
if ($this->_timezone != $oldzone) {
date_default_timezone_set($this->_timezone);
}
$result = ($gmt) ? @gmdate($format) : @date($format);
date_default_timezone_set($oldzone);
return $result;
}
if (abs($timestamp) <= 0x7FFFFFFF) {
$oldzone = @date_default_timezone_get();
if ($this->_timezone != $oldzone) {
date_default_timezone_set($this->_timezone);
}
$result = ($gmt) ? @gmdate($format, $timestamp) : @date($format, $timestamp);
date_default_timezone_set($oldzone);
return $result;
}
// check on false or null alone failes
if (empty($gmt)) {
$timestamp -= $this->_offset;
}
$date = $this->getDateParts($timestamp, true);
$length = strlen($format);
$output = '';
for ($i = 0; $i < $length; $i++) {
switch($format[$i]) {
// day formats
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?