commoncount
7/27/2018 - 2:54 AM

## 周期去除节假日

``````/**
* 度量周期去除节假日和周末
* 算法：得到正常周末和法定节假日，然后减去这段时间
* @param  string \$end
* @param  string \$start
* @param  string \$returnType 返回单位
* @param  int    \$precision 精度，表示保留小数点后几位
* @access public
* @return string
*/
public function minusHoliday(\$end, \$start, \$returnType='hour', \$precision = 0)
{
if(\$end == '0000-00-00 00:00:00' || \$start == '0000-00-00 00:00:00' || empty(\$end) || empty(\$start))
return '';

//如果开始|结束时间在节假日，则时间重置为后面最近的一个工作日
\$startDate = \$this->nextWorkDay(\$start);
\$endDate = \$this->nextWorkDay(\$end);
if(\$startDate>\$endDate) return 0;
\$diffPeriod = '';
\$precision = 0;
switch (\$returnType){
case 'hour':
\$holidaysArr = \$this->dao->select('id,hdtime,hdduty')->from(TABLE_HOLIDAY)->where('hdtime')->between(\$startDate,\$endDate)->andWhere('hdduty')->eq('y')->fetchAll('id');
\$minusDays = \$this->getMinusDays(\$startDate, \$endDate)+count(\$holidaysArr);
\$diffPeriod = helper::diffHour(\$end, \$start,\$precision) - (\$minusDays*24);
break;
case 'day':
\$holidaysArr = \$this->dao->select('id,hdtime,hdduty')->from(TABLE_HOLIDAY)->where('hdtime')->between(\$startDate,\$endDate)->andWhere('hdduty')->eq('y')->fetchAll('id');
\$minusDays = \$this->getMinusDays(\$startDate, \$endDate)+count(\$holidaysArr);
\$diffPeriod = helper::diffDate(\$end, \$start) - \$minusDays;
break;
case 'month':

break;
default:

return round((strtotime(\$end) - strtotime(\$start)) / 3600, \$precision);
break;
}
return \$diffPeriod;
}

/**
* 计算周期内需要减掉的普通周末
* @param date \$start Y-m-d
* @param date \$end Y-m-d
* return int 天数  */
public function getMinusDays(\$start, \$end){
if(strtotime(\$start) > strtotime(\$end)){
list(\$start,\$end) = array(\$end,\$start);
}
\$minus = 0;
for(\$date=\$start; \$date<=\$end; \$date = date("Y-m-d", strtotime(\$date." +1 days"))){
//0(星期天)"至"6(星期六),判断是普通的周末还是节假日中的周末
\$weekDay = date("w", strtotime(\$date));
if(\$weekDay == 0 ||\$weekDay == 6){
//是法定节假日的话，后面直接从holidays里计算
\$checkHoliday = \$this->dao->select('id,hdtime,hdduty')->from(TABLE_HOLIDAY)->where('hdtime')->eq(\$date)->fetch();
if(\$checkHoliday){
//if(\$checkHoliday->hdduty == 'n'){}
}else{
\$minus += 1;   //正常周末
}
}
}
return \$minus;
}

/**
* 判断日期是否是节假日
* @param date \$date
* return boolean  */
public function isHoliday(\$date){
\$checkHoliday = \$this->dao->select('id,hdtime,hdduty')->from(TABLE_HOLIDAY)->where('hdtime')->eq(\$date)->fetch();
if(\$checkHoliday){
return (\$checkHoliday->hdduty == 'n')? false:true;
}else{
\$weekDay = date("w", strtotime(\$date));
if(\$weekDay == 0 ||\$weekDay == 6){
return true;
}else{
return false;
}
}
}

/**
* 如果在节假日中，获取最近的工作日，如果\$date本身就是工作日，则返回\$date
* 用于周期计算扣除节假日
* @param date \$date
* return boolean  */
public function nextWorkDay(&\$dateTime){
\$tmpDate = date('Y-m-d',strtotime(\$dateTime));
\$resetDate = false;
while (1){
\$isHoliday = \$this->isHoliday(\$tmpDate);
if(\$isHoliday){
\$resetDate = true;
\$tmpDate = date("Y-m-d", strtotime(\$tmpDate." +1 days"));
}else{
\$date = \$tmpDate;
if(\$resetDate) \$dateTime = \$tmpDate;
break;
}
}
return \$date;
}``````