代码功能更新
This commit is contained in:
Executable
+358
@@ -0,0 +1,358 @@
|
||||
<?php
|
||||
|
||||
namespace laytp\library;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
|
||||
/**
|
||||
* 日期时间处理类
|
||||
*/
|
||||
class Date
|
||||
{
|
||||
const YEAR = 31536000;
|
||||
const MONTH = 2592000;
|
||||
const WEEK = 604800;
|
||||
const DAY = 86400;
|
||||
const HOUR = 3600;
|
||||
const MINUTE = 60;
|
||||
|
||||
/**
|
||||
* 计算两个时区间相差的时长,单位为秒
|
||||
* $seconds = self::offset('America/Chicago', 'GMT');
|
||||
* [!!] A list of time zones that PHP supports can be found at
|
||||
* <http://php.net/timezones>.
|
||||
*
|
||||
* @param $remote
|
||||
* @param null $local
|
||||
* @param null $now
|
||||
* @return int
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function offset($remote, $local = null, $now = null)
|
||||
{
|
||||
if ($local === null) {
|
||||
// Use the default timezone
|
||||
$local = date_default_timezone_get();
|
||||
}
|
||||
if (is_int($now)) {
|
||||
// Convert the timestamp into a string
|
||||
$now = date(DateTime::RFC2822, $now);
|
||||
}
|
||||
// Create timezone objects
|
||||
$zone_remote = new DateTimeZone($remote);
|
||||
$zone_local = new DateTimeZone($local);
|
||||
// Create date objects from timezones
|
||||
$time_remote = new DateTime($now, $zone_remote);
|
||||
$time_local = new DateTime($now, $zone_local);
|
||||
// Find the offset
|
||||
$offset = $zone_remote->getOffset($time_remote) - $zone_local->getOffset($time_local);
|
||||
return $offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算两个时间戳之间相差的时间
|
||||
*
|
||||
* $span = self::span(60, 182, 'minutes,seconds'); // array('minutes' => 2, 'seconds' => 2)
|
||||
* $span = self::span(60, 182, 'minutes'); // 2
|
||||
*
|
||||
* @param int $remote timestamp to find the span of
|
||||
* @param int $local timestamp to use as the baseline
|
||||
* @param string $output formatting string
|
||||
* @return string when only a single output is requested
|
||||
* @return array associative list of all outputs requested
|
||||
* @from https://github.com/kohana/ohanzee-helpers/blob/master/src/Date.php
|
||||
*/
|
||||
public static function span($remote, $local = null, $output = 'years,months,weeks,days,hours,minutes,seconds')
|
||||
{
|
||||
// Normalize output
|
||||
$output = trim(strtolower((string)$output));
|
||||
if (!$output) {
|
||||
// Invalid output
|
||||
return false;
|
||||
}
|
||||
// Array with the output formats
|
||||
$output = preg_split('/[^a-z]+/', $output);
|
||||
// Convert the list of outputs to an associative array
|
||||
$output = array_combine($output, array_fill(0, count($output), 0));
|
||||
// Make the output values into keys
|
||||
extract(array_flip($output), EXTR_SKIP);
|
||||
if ($local === null) {
|
||||
// Calculate the span from the current time
|
||||
$local = time();
|
||||
}
|
||||
// Calculate timespan (seconds)
|
||||
$timespan = abs($remote - $local);
|
||||
if (isset($output['years'])) {
|
||||
$timespan -= self::YEAR * ($output['years'] = (int)floor($timespan / self::YEAR));
|
||||
}
|
||||
if (isset($output['months'])) {
|
||||
$timespan -= self::MONTH * ($output['months'] = (int)floor($timespan / self::MONTH));
|
||||
}
|
||||
if (isset($output['weeks'])) {
|
||||
$timespan -= self::WEEK * ($output['weeks'] = (int)floor($timespan / self::WEEK));
|
||||
}
|
||||
if (isset($output['days'])) {
|
||||
$timespan -= self::DAY * ($output['days'] = (int)floor($timespan / self::DAY));
|
||||
}
|
||||
if (isset($output['hours'])) {
|
||||
$timespan -= self::HOUR * ($output['hours'] = (int)floor($timespan / self::HOUR));
|
||||
}
|
||||
if (isset($output['minutes'])) {
|
||||
$timespan -= self::MINUTE * ($output['minutes'] = (int)floor($timespan / self::MINUTE));
|
||||
}
|
||||
// Seconds ago, 1
|
||||
if (isset($output['seconds'])) {
|
||||
$output['seconds'] = $timespan;
|
||||
}
|
||||
if (count($output) === 1) {
|
||||
// Only a single output was requested, return it
|
||||
return array_pop($output);
|
||||
}
|
||||
// Return array
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化 UNIX 时间戳为人易读的字符串
|
||||
*
|
||||
* @param int Unix 时间戳
|
||||
* @param mixed $local 本地时间
|
||||
*
|
||||
* @return string 格式化的日期字符串
|
||||
*/
|
||||
public static function human($remote, $local = null)
|
||||
{
|
||||
$timediff = (is_null($local) || $local ? time() : $local) - $remote;
|
||||
$chunks = [
|
||||
[60 * 60 * 24 * 365, 'year'],
|
||||
[60 * 60 * 24 * 30, 'month'],
|
||||
[60 * 60 * 24 * 7, 'week'],
|
||||
[60 * 60 * 24, 'day'],
|
||||
[60 * 60, 'hour'],
|
||||
[60, 'minute'],
|
||||
[1, 'second'],
|
||||
];
|
||||
|
||||
for ($i = 0, $j = count($chunks); $i < $j; $i++) {
|
||||
$seconds = $chunks[$i][0];
|
||||
$name = $chunks[$i][1];
|
||||
if (($count = floor($timediff / $seconds)) != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return __("%d {$name}%s ago", $count, ($count > 1 ? 's' : ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取一个基于时间偏移的Unix时间戳
|
||||
*
|
||||
* @param string $type 时间类型,默认为day,可选minute,hour,day,week,month,quarter,year
|
||||
* @param int $offset 时间偏移量 默认为0,正数表示当前type之后,负数表示当前type之前
|
||||
* @param string $position 时间的开始或结束,默认为begin,可选前(begin,start,first,front),end
|
||||
* @param int $year 基准年,默认为null,即以当前年为基准
|
||||
* @param int $month 基准月,默认为null,即以当前月为基准
|
||||
* @param int $day 基准天,默认为null,即以当前天为基准
|
||||
* @param int $hour 基准小时,默认为null,即以当前年小时基准
|
||||
* @param int $minute 基准分钟,默认为null,即以当前分钟为基准
|
||||
* @return int 处理后的Unix时间戳
|
||||
*/
|
||||
public static function unixtime($type = 'day', $offset = 0, $position = 'begin', $year = null, $month = null, $day = null, $hour = null, $minute = null)
|
||||
{
|
||||
$year = is_null($year) ? date('Y') : $year;
|
||||
$month = is_null($month) ? date('m') : $month;
|
||||
$day = is_null($day) ? date('d') : $day;
|
||||
$hour = is_null($hour) ? date('H') : $hour;
|
||||
$minute = is_null($minute) ? date('i') : $minute;
|
||||
$position = in_array($position, ['begin', 'start', 'first', 'front']);
|
||||
|
||||
switch ($type) {
|
||||
case 'minute':
|
||||
$time = $position ? mktime($hour, $minute + $offset, 0, $month, $day, $year) : mktime($hour, $minute + $offset, 59, $month, $day, $year);
|
||||
break;
|
||||
case 'hour':
|
||||
$time = $position ? mktime($hour + $offset, 0, 0, $month, $day, $year) : mktime($hour + $offset, 59, 59, $month, $day, $year);
|
||||
break;
|
||||
case 'day':
|
||||
$time = $position ? mktime(0, 0, 0, $month, $day + $offset, $year) : mktime(23, 59, 59, $month, $day + $offset, $year);
|
||||
break;
|
||||
case 'week':
|
||||
$time = $position ?
|
||||
mktime(0, 0, 0, $month, $day - date("w", mktime(0, 0, 0, $month, $day, $year)) + 1 - 7 * (-$offset), $year) :
|
||||
mktime(23, 59, 59, $month, $day - date("w", mktime(0, 0, 0, $month, $day, $year)) + 7 - 7 * (-$offset), $year);
|
||||
break;
|
||||
case 'month':
|
||||
$time = $position ? mktime(0, 0, 0, $month + $offset, 1, $year) : mktime(23, 59, 59, $month + $offset, cal_days_in_month(CAL_GREGORIAN, $month + $offset, $year), $year);
|
||||
break;
|
||||
case 'quarter':
|
||||
$time = $position ?
|
||||
mktime(0, 0, 0, 1 + ((ceil(date('n', mktime(0, 0, 0, $month, $day, $year)) / 3) + $offset) - 1) * 3, 1, $year) :
|
||||
mktime(23, 59, 59, (ceil(date('n', mktime(0, 0, 0, $month, $day, $year)) / 3) + $offset) * 3, cal_days_in_month(CAL_GREGORIAN, (ceil(date('n', mktime(0, 0, 0, $month, $day, $year)) / 3) + $offset) * 3, $year), $year);
|
||||
break;
|
||||
case 'year':
|
||||
$time = $position ? mktime(0, 0, 0, 1, 1, $year + $offset) : mktime(23, 59, 59, 12, 31, $year + $offset);
|
||||
break;
|
||||
default:
|
||||
$time = mktime($hour, $minute, 0, $month, $day, $year);
|
||||
break;
|
||||
}
|
||||
return $time;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取某个日期属于一年中的第几周
|
||||
* @param $date
|
||||
* @return false|int|string
|
||||
*/
|
||||
public static function getWeekNum($date='')
|
||||
{
|
||||
$date = $date ? $date : date('Y-m-d');
|
||||
|
||||
$year = date('Y', strtotime($date));
|
||||
|
||||
$yearBegin = strtotime($year.'-1-1');
|
||||
|
||||
$month = intval(date('m', strtotime($date)));
|
||||
|
||||
if( date('W', $yearBegin) == 1 ){
|
||||
return date('W', strtotime($date));
|
||||
}else if($month == 1 && date('W', $yearBegin) > 50){
|
||||
return 1;
|
||||
}else{
|
||||
return date('W', strtotime($date)) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据日期,获取周信息
|
||||
* @param $now string 日期,举例: 2021-01-01
|
||||
* @return array
|
||||
*/
|
||||
public static function getWeekInfo($now)
|
||||
{
|
||||
$str = [];
|
||||
//$first =1 表示每周星期一为开始日期 0表示每周日为开始日期
|
||||
$str['year'] = date('Y', strtotime($now));
|
||||
$first = 1;
|
||||
//当日在整年中的第几周
|
||||
$str['week'] = date('W', strtotime($now));
|
||||
//获取当前周的第几天 周日是 0 周一到周六是 1 - 6
|
||||
$w = date('w', strtotime($now));
|
||||
//获取本周开始日期,如果$w是0,则表示周日,减去 6 天
|
||||
$weekStart = date('Y-m-d', strtotime("$now -" . ($w ? $w - $first : 6) . ' days'));
|
||||
$str['week_start'] = $weekStart;
|
||||
//本周结束日期
|
||||
$weekEnd = date('Y-m-d', strtotime("$weekStart +6 days"));
|
||||
$str['week_end'] = $weekEnd;
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 某去某年第几周的周信息
|
||||
* @param $year
|
||||
* @param int $week
|
||||
* @return mixed
|
||||
*/
|
||||
public static function weekDay($year, $week=1){
|
||||
$yearStart = mktime(0,0,0,1,1, $year);
|
||||
$yearEnd = mktime(0,0,0,12,31, $year);
|
||||
|
||||
$start = $yearStart;//把第一天做为第一周的开始
|
||||
$end = strtotime('+1 sunday', $yearStart);//把第一个周日作为第一周的结束
|
||||
|
||||
$lastStart = strtotime('-1 monday', $yearStart);//把最后一个周一作为最后一周的开始
|
||||
$lastEnd = $yearEnd;//把最后一天作为最后一周的结束
|
||||
|
||||
$totalWeekNum = intval(date('W', $yearStart));
|
||||
|
||||
if($week == 1){
|
||||
$weekday['begin'] = $start;//把第一天做为第一周的开始
|
||||
$weekday['begin_date'] = date('Y-m-d', $start);//把第一天做为第一周的开始
|
||||
$weekday['end'] = $end;//把第一个周日作为第一周的结束
|
||||
$weekday['end_date'] = date('Y-m-d', $end);//把第一个周日作为第一周的结束
|
||||
}else if($week == $totalWeekNum){
|
||||
$weekday['begin'] = $lastStart;//把最后一个周一作为最后一周的开始
|
||||
$weekday['begin_date'] = date('Y-m-d', $lastStart);//把第一天做为第一周的开始
|
||||
$weekday['end'] = $lastEnd;//把第一个周日作为第一周的结束
|
||||
$weekday['end_date'] = date('Y-m-d', $lastEnd);//把第一个周日作为第一周的结束
|
||||
}else if($week > 1 && $week < $totalWeekNum){
|
||||
$weekday['begin'] = strtotime('+' . ($week-1) . ' monday', $end);
|
||||
$weekday['begin_date'] = date('Y-m-d', $weekday['begin']);
|
||||
$weekday['end'] = strtotime('+' . ($week-1) . ' sunday', $end + 24 * 60 * 60);
|
||||
$weekday['end_date'] = date('Y-m-d', $weekday['end']);
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
|
||||
$weekday['week'] = $week;
|
||||
$weekday['totalWeekNum'] = $totalWeekNum;
|
||||
|
||||
return $weekday;
|
||||
}
|
||||
|
||||
/**
|
||||
* 友好的时间显示
|
||||
*
|
||||
* @param int $sTime 待显示的时间
|
||||
* @param string $type 类型. normal | mohu | full | ymd | other
|
||||
* @param string $alt 已失效
|
||||
* @return string
|
||||
*/
|
||||
public static function friendlyDate($sTime,$type = 'default',$alt = 'false') {
|
||||
//sTime=源时间,cTime=当前时间,dTime=时间差
|
||||
$cTime = time();
|
||||
$dTime = $cTime - $sTime;
|
||||
$dDay = intval(date("z",$cTime)) - intval(date("z",$sTime));
|
||||
//$dDay = intval($dTime/3600/24);
|
||||
$dYear = intval(date("Y",$cTime)) - intval(date("Y",$sTime));
|
||||
//normal:n秒前,n分钟前,n小时前,日期
|
||||
if($type=='normal'){
|
||||
if($dTime == 0){
|
||||
return '现在';
|
||||
}elseif( $dTime < 60 ){
|
||||
return $dTime."秒前";
|
||||
}elseif( $dTime < 3600 ){
|
||||
return intval($dTime/60)."分钟前";
|
||||
//今天的数据.年份相同.日期相同.
|
||||
}elseif( $dYear==0 && $dDay == 0 ){
|
||||
//return intval($dTime/3600)."小时前";
|
||||
return '今天'.date('H:i',$sTime);
|
||||
}elseif($dYear==0){
|
||||
return date("m月d日 H:i",$sTime);
|
||||
}else{
|
||||
return date("Y-m-d H:i",$sTime);
|
||||
}
|
||||
}elseif($type=='mohu'){
|
||||
if( $dTime < 60 ){
|
||||
return $dTime."秒前";
|
||||
}elseif( $dTime < 3600 ){
|
||||
return intval($dTime/60)."分钟前";
|
||||
}elseif( $dTime >= 3600 && $dDay == 0 ){
|
||||
return intval($dTime/3600)."小时前";
|
||||
}elseif( $dDay > 0 && $dDay<=7 ){
|
||||
return intval($dDay)."天前";
|
||||
}elseif( $dDay > 7 && $dDay <= 30 ){
|
||||
return intval($dDay/7) . '周前';
|
||||
}elseif( $dDay > 30 ){
|
||||
return intval($dDay/30) . '个月前';
|
||||
}
|
||||
//full: Y-m-d , H:i:s
|
||||
}elseif($type=='full'){
|
||||
return date("Y-m-d , H:i:s",$sTime);
|
||||
}elseif($type=='ymd'){
|
||||
return date("Y-m-d",$sTime);
|
||||
}else{
|
||||
if( $dTime < 60 ){
|
||||
return $dTime."秒前";
|
||||
}elseif( $dTime < 3600 ){
|
||||
return intval($dTime/60)."分钟前";
|
||||
}elseif( $dTime >= 3600 && $dDay == 0 ){
|
||||
return intval($dTime/3600)."小时前";
|
||||
}elseif($dYear==0){
|
||||
return date("Y-m-d H:i:s",$sTime);
|
||||
}else{
|
||||
return date("Y-m-d H:i:s",$sTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user