<?php // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK IT ] // +---------------------------------------------------------------------- // | Copyright (c) 2009 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- // | Author: liu21st <liu21st@gmail.com> // +---------------------------------------------------------------------- namespace Org\Util; /** * 日期时间操作类 * * @category ORG * @package ORG * @subpackage Date * @author liu21st <liu21st@gmail.com> * @version $Id: Date.class.php 2662 2012-01-26 06:32:50Z liu21st $ */ class Date { /** * 日期的时间戳 * * @var integer * @access protected */ protected $date; /** * 时区 * * @var integer * @access protected */ protected $timezone; /** * 年 * * @var integer * @access protected */ protected $year; /** * 月 * * @var integer * @access protected */ protected $month; /** * 日 * * @var integer * @access protected */ protected $day; /** * 时 * * @var integer * @access protected */ protected $hour; /** * 分 * * @var integer * @access protected */ protected $minute; /** * 秒 * * @var integer * @access protected */ protected $second; /** * 星期的数字表示 * * @var integer * @access protected */ protected $weekday; /** * 星期的完整表示 * * @var string * @access protected */ protected $cWeekday; /** * 一年中的天数 0-365 * * @var integer * @access protected */ protected $yDay; /** * 月份的完整表示 * * @var string * @access protected */ protected $cMonth; /** * 日期CDATE表示 * * @var string * @access protected */ protected $CDATE; /** * 日期的YMD表示 * * @var string * @access protected */ protected $YMD; /** * 时间的输出表示 * * @var string * @access protected */ protected $CTIME; // 星期的输出 protected $Week = array( "日", "一", "二", "三", "四", "五", "六" ); /** * 架构函数 * 创建一个Date对象 * * @param mixed $date * 日期 * @static * * @access public */ public function __construct($date = '') { // 分析日期 $this->date = $this->parse($date); $this->setDate($this->date); } public function __get($name) { return $this->$name; } /** * 获取CDATE * * @return string */ public function getCDATE(){ return $this->CDATE; } /** * 日期分析 * 返回时间戳 * * @static * * @access public * @param mixed $date * 日期 * @return string */ public function parse($date) { if (is_string($date)) { if (($date == "") || rstrtotime($date) == - 1) { // 为空默认取得当前时间戳 $tmpdate = time(); } else { // 把字符串转换成UNIX时间戳 $tmpdate = rstrtotime($date); } } elseif (is_null($date)) { // 为空默认取得当前时间戳 $tmpdate = time(); } elseif (is_numeric($date)) { // 数字格式直接转换为时间戳 $tmpdate = $date; } else { if (get_class($date) == "Date") { // 如果是Date对象 $tmpdate = $date->date; } else { // 默认取当前时间戳 $tmpdate = time(); } } return $tmpdate; } /** * 验证日期数据是否有效 * * @access public * @param mixed $date * 日期数据 * @return string */ public function valid($date) {} /** * 日期参数设置 * * @static * * @access public * @param integer $date * 日期时间戳 * @return void */ public function setDate($date) { $offset = cfg('TIME_OFFSET'); // 默认时区为 +8 if (! $offset) { $offset = 8; } // 时间戳转换为秒为单位 $date = to_second_time($date); // 时区偏移 $date += $offset * 3600; $dateArray = getdate($date); // 还原时间戳的时区偏移 $dateArray[0] -= $offset * 3600; $this->date = $dateArray[0]; // 时间戳 $this->second = $dateArray["seconds"]; // 秒 $this->minute = $dateArray["minutes"]; // 分 $this->hour = $dateArray["hours"]; // 时 $this->day = $dateArray["mday"]; // 日 $this->month = $dateArray["mon"]; // 月 $this->year = $dateArray["year"]; // 年 $this->weekday = $dateArray["wday"]; // 星期 0~6 $this->cWeekday = '星期' . $this->Week[$this->weekday]; // $dateArray["weekday"]; //星期完整表示 $this->yDay = $dateArray["yday"]; // 一年中的天数 0-365 $this->cMonth = $dateArray["month"]; // 月份的完整表示 $this->CDATE = $this->format("%Y-%m-%d"); // 日期表示 $this->YMD = $this->format("%Y%m%d"); // 简单日期 $this->CTIME = $this->format("%H:%M:%S"); // 时间表示 return; } /** * 日期格式化 * 默认返回 1970-01-01 11:30:45 格式 * * @access public * @param string $format * 格式化参数 * @return string */ public function format($format = "%Y-%m-%d %H:%M:%S") { return strftime($format, $this->date); } /** * 是否为闰年 * * @static * * @access public * @return string */ public function isLeapYear($year = '') { if (empty($year)) { $year = $this->year; } return ((($year % 4) == 0) && (($year % 100) != 0) || (($year % 400) == 0)); } /** * 计算日期差 * w - weeks * d - days * h - hours * m - minutes * s - seconds * * @static * * @access public * @param mixed $date * 要比较的日期 * @param string $elaps * 比较跨度 * @return integer */ public function dateDiff($date, $elaps = "d") { $__DAYS_PER_WEEK__ = (7); $__DAYS_PER_MONTH__ = (30); $__DAYS_PER_YEAR__ = (365); $__HOURS_IN_A_DAY__ = (24); $__MINUTES_IN_A_DAY__ = (1440); $__SECONDS_IN_A_DAY__ = (86400); // 计算天数差 $__DAYSELAPS = ($this->parse($date) - $this->date) / $__SECONDS_IN_A_DAY__; switch ($elaps) { case "y": // 转换成年 $__DAYSELAPS = $__DAYSELAPS / $__DAYS_PER_YEAR__; break; case "M": // 转换成月 $__DAYSELAPS = $__DAYSELAPS / $__DAYS_PER_MONTH__; break; case "w": // 转换成星期 $__DAYSELAPS = $__DAYSELAPS / $__DAYS_PER_WEEK__; break; case "h": // 转换成小时 $__DAYSELAPS = $__DAYSELAPS * $__HOURS_IN_A_DAY__; break; case "m": // 转换成分钟 $__DAYSELAPS = $__DAYSELAPS * $__MINUTES_IN_A_DAY__; break; case "s": // 转换成秒 $__DAYSELAPS = $__DAYSELAPS * $__SECONDS_IN_A_DAY__; break; } return $__DAYSELAPS; } /** * 两个日期之间间隔的所有日期 * * @param $date 要比较的日期 * @param int $precision 要求精度, 0: 秒; 1: 毫秒 */ public function betweenDays($date, $precision = 0){ $dt_start = $this->date; $dt_end = $this->parse($date); $days = array(); while ($dt_start <= $dt_end){ $days[] = (0 == $precision ? $dt_start : ($dt_start * 1000)); $dt_start = rstrtotime('+1 day',$dt_start); } return $days; } /** * 人性化的计算日期差 * * @static * * @access public * @param mixed $time * 要比较的时间 * @param mixed $precision * 返回的精度 * @return string */ public function timeDiff($time, $precision = false) { if (! is_numeric($precision) && ! is_bool($precision)) { static $_diff = array( 'y' => '年', 'M' => '个月', 'd' => '天', 'w' => '周', 's' => '秒', 'h' => '小时', 'm' => '分钟' ); return ceil($this->dateDiff($time, $precision)) . $_diff[$precision] . '前'; } $diff = abs($this->parse($time) - $this->date); static $chunks = array( array( 31536000, '年' ), array( 2592000, '个月' ), array( 604800, '周' ), array( 86400, '天' ), array( 3600, '小时' ), array( 60, '分钟' ), array( 1, '秒' ) ); $count = 0; $since = ''; for ($i = 0; $i < count($chunks); $i ++) { if ($diff >= $chunks[$i][0]) { $num = floor($diff / $chunks[$i][0]); $since .= sprintf('%d' . $chunks[$i][1], $num); $diff = (int) ($diff - $chunks[$i][0] * $num); $count ++; if (! $precision || $count >= $precision) { break; } } } return $since . '前'; } /** * 返回周的某一天 返回Date对象 * * @access public * @return Date */ public function getDayOfWeek($n) { $week = array( 0 => 'sunday', 1 => 'monday', 2 => 'tuesday', 3 => 'wednesday', 4 => 'thursday', 5 => 'friday', 6 => 'saturday' ); return new Date($week[$n]); } /** * 计算周的第一天 返回Date对象 * * @access public * @return Date */ public function firstDayOfWeek() { return $this->getDayOfWeek(1); } /** * 计算月份的第一天 返回Date对象 * * @access public * @return Date */ public function firstDayOfMonth() { return new Date(mktime(0, 0, 0, $this->month, 1, $this->year)); } /** * 计算年份的第一天 返回Date对象 * * @access public * @return Date */ public function firstDayOfYear() { return new Date(mktime(0, 0, 0, 1, 1, $this->year)); } /** * 计算周的最后一天 返回Date对象 * * @access public * @return Date */ public function lastDayOfWeek() { return $this->getDayOfWeek(0); } /** * 计算月份的最后一天 返回Date对象 * * @access public * @return Date */ public function lastDayOfMonth() { return new Date(mktime(0, 0, 0, $this->month + 1, 0, $this->year)); } /** * 计算年份的最后一天 返回Date对象 * * @access public * @return Date */ public function lastDayOfYear() { return new Date(mktime(0, 0, 0, 1, 0, $this->year + 1)); } /** * 计算月份的最大天数 * * @access public * @return integer */ public function maxDayOfMonth() { $result = $this->dateDiff(rstrtotime($this->dateAdd(1, 'm')), 'd'); return $result; } /** * 取得指定间隔日期 * yyyy - 年 * q - 季度 * m - 月 * y - day of year * d - 日 * w - 周 * ww - week of year * h - 小时 * n - 分钟 * s - 秒 * * @access public * @param integer $number * 间隔数目 * @param string $interval * 比较类型 * @return Date */ public function dateAdd($number = 0, $interval = "d") { $hours = $this->hour; $minutes = $this->minute; $seconds = $this->second; $month = $this->month; $day = $this->day; $year = $this->year; switch ($interval) { case "yyyy": // ---Add $number to year $year += $number; break; case "q": // ---Add $number to quarter $month += ($number * 3); break; case "m": // ---Add $number to month $month += $number; break; case "y": case "d": case "w": // ---Add $number to day of year, day, day of week $day += $number; break; case "ww": // ---Add $number to week $day += ($number * 7); break; case "h": // ---Add $number to hours $hours += $number; break; case "n": // ---Add $number to minutes $minutes += $number; break; case "s": // ---Add $number to seconds $seconds += $number; break; } return new Date(mktime($hours, $minutes, $seconds, $month, $day, $year)); } /** * 日期数字转中文 * 用于日和月、周 * * @static * * @access public * @param integer $number * 日期数字 * @return string */ public function numberToCh($number) { $number = intval($number); $array = array( '一', '二', '三', '四', '五', '六', '七', '八', '九', '十' ); $str = ''; if ($number == 0) { $str .= "十"; } if ($number < 10) { $str .= $array[$number - 1]; } elseif ($number < 20) { $str .= "十" . $array[$number - 11]; } elseif ($number < 30) { $str .= "二十" . $array[$number - 21]; } else { $str .= "三十" . $array[$number - 31]; } return $str; } /** * 年份数字转中文 * * @static * * @access public * @param integer $yearStr * 年份数字 * @param boolean $flag * 是否显示公元 * @return string */ public function yearToCh($yearStr, $flag = false) { $array = array( '零', '一', '二', '三', '四', '五', '六', '七', '八', '九' ); $str = $flag ? '公元' : ''; for ($i = 0; $i < 4; $i ++) { $str .= $array[substr($yearStr, $i, 1)]; } return $str; } /** * 判断日期 所属 干支 生肖 星座 * type 参数:XZ 星座 GZ 干支 SX 生肖 * * @static * * @access public * @param string $type * 获取信息类型 * @return string */ public function magicInfo($type) { $result = ''; $m = $this->month; $y = $this->year; $d = $this->day; switch ($type) { case 'XZ': // 星座 $XZDict = array( '摩羯', '宝瓶', '双鱼', '白羊', '金牛', '双子', '巨蟹', '狮子', '处女', '天秤', '天蝎', '射手' ); $Zone = array( 1222, 122, 222, 321, 421, 522, 622, 722, 822, 922, 1022, 1122, 1222 ); if ((100 * $m + $d) >= $Zone[0] || (100 * $m + $d) < $Zone[1]) { $i = 0; } else { for ($i = 1; $i < 12; $i ++) { if ((100 * $m + $d) >= $Zone[$i] && (100 * $m + $d) < $Zone[$i + 1]) { break; } } } $result = $XZDict[$i] . '座'; break; case 'GZ': // 干支 $GZDict = array( array( '甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸' ), array( '子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥' ) ); $i = $y - 1900 + 36; $result = $GZDict[0][$i % 10] . $GZDict[1][$i % 12]; break; case 'SX': // 生肖 $SXDict = array( '鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪' ); $result = $SXDict[($y - 4) % 12]; break; } return $result; } public function __toString() { return $this->format(); } }