Php 我有一个最后期限是5天,我需要添加+;每非工作日(周末或节假日)1天
我试图制定一个规则,我的最后期限是5天,我需要为每个非工作日(周末或假日)加上+1天。还有下表的节假日提醒,如果最后一天不能是周末或节假日 我的桌子假日 我已经试过了,但没有好结果Php 我有一个最后期限是5天,我需要添加+;每非工作日(周末或节假日)1天,php,mysql,Php,Mysql,我试图制定一个规则,我的最后期限是5天,我需要为每个非工作日(周末或假日)加上+1天。还有下表的节假日提醒,如果最后一天不能是周末或节假日 我的桌子假日 我已经试过了,但没有好结果 //The function returns the no. of business days between two dates and it skips the holidays function getWorkingDays($startDate,$endDate,$holidays){ // do
//The function returns the no. of business days between two dates and it skips the holidays
function getWorkingDays($startDate,$endDate,$holidays){
// do strtotime calculations just once
$endDate = strtotime($endDate);
$startDate = strtotime($startDate);
//The total number of days between the two dates. We compute the no. of seconds and divide it to 60*60*24
//We add one to inlude both dates in the interval.
$days = ($endDate - $startDate) / 86400 + 1;
$no_full_weeks = floor($days / 7);
$no_remaining_days = fmod($days, 7);
//It will return 1 if it's Monday,.. ,7 for Sunday
$the_first_day_of_week = date("N", $startDate);
$the_last_day_of_week = date("N", $endDate);
//---->The two can be equal in leap years when february has 29 days, the equal sign is added here
//In the first case the whole interval is within a week, in the second case the interval falls in two weeks.
if ($the_first_day_of_week <= $the_last_day_of_week) {
if ($the_first_day_of_week <= 6 && 6 <= $the_last_day_of_week) $no_remaining_days--;
if ($the_first_day_of_week <= 7 && 7 <= $the_last_day_of_week) $no_remaining_days--;
}
else {
// (edit by Tokes to fix an edge case where the start day was a Sunday
// and the end day was NOT a Saturday)
// the day of the week for start is later than the day of the week for end
if ($the_first_day_of_week == 7) {
// if the start date is a Sunday, then we definitely subtract 1 day
$no_remaining_days++;
if ($the_last_day_of_week == 6) {
// if the end date is a Saturday, then we subtract another day
$no_remaining_days++;
}
}
else {
// the start date was a Saturday (or earlier), and the end date was (Mon..Fri)
// so we skip an entire weekend and subtract 2 days
$no_remaining_days += 2;
}
}
//The no. of business days is: (number of weeks between the two dates) * (5 working days) + the remainder
//---->february in none leap years gave a remainder of 0 but still calculated weekends between first and last day, this is one way to fix it
$workingDays = $no_full_weeks * 5;
if ($no_remaining_days > 0 )
{
$workingDays += $no_remaining_days;
}
//We subtract the holidays
foreach($holidays as $holiday){
$time_stamp=strtotime($holiday->data);
//If the holiday doesn't fall in weekend
if ($startDate <= $time_stamp && date("N",$time_stamp) != 6 && date("N",$time_stamp) != 7)
$workingDays++;
}
return $workingDays;
}
//函数返回两个日期之间的工作日数,并跳过假期
函数getWorkingDays($startDate、$endDate、$holidays){
//只进行一次strotime计算
$endDate=strottime($endDate);
$startDate=strottime($startDate);
//两个日期之间的总天数。我们计算秒数并将其除以60*60*24
//我们在间隔中的两个日期中都添加一个。
$days=($endDate-$startDate)/86400+1;
$no_full_weeks=最低限额($days/7);
$no_剩余天数=fmod($d,7);
//如果是星期一,它将返回1,如果是星期天,它将返回7
$每周的第一天=日期(“N”,开始日期);
$U周的最后一天=日期(“N”,$endDate);
//---->二者在闰年中可以相等,二月有29天,这里加上等号
//在第一种情况下,整个间隔在一周内,在第二种情况下,间隔在两周内。
如果使用DateTime
和DateInterval
将($作为一周的第一天),您可以向开始日期添加若干个工作日,并可选择假日数组:
function getDeadline($start_date, $working_days, array $holiday_dates = array())
{
$date = DateTime::createFromFormat('Y-m-d', $start_date);
$interval = new DateInterval('P1D'); // one day
$holiday_dates = array_flip($holiday_dates); // so we can use isset to check for holidays
while (
$date->format('N') >= 6 // weekend day
|| isset($holiday_dates[$date->format('Y-m-d')]) // OR holiday
|| $working_days-- > 0 // OR deadline working days left to add
) {
$date->add($interval); // move to next day
}
return $date->format('Y-m-d');
}
测试如下:
var_dump(getDeadline('2017-12-21', 5)); // only weekends
var_dump(getDeadline('2017-12-21', 5, array('2017-12-22', '2017-12-26'))); // weekends and holidays
给出输出:
string(10) "2017-12-28"
string(10) "2018-01-01"
array(6) {
[0]=>
string(10) "2017-12-22"
[1]=>
string(10) "2017-12-26"
[2]=>
string(10) "2017-12-27"
[3]=>
string(10) "2018-01-01"
[4]=>
string(10) "2018-01-02"
[5]=>
string(10) "2018-01-03"
}
string(10) "2018-01-05"
由于您的假期存储在mysql中,您可以使用如下函数在单个查询中提取假期:
function getHolidays($start_date)
{
$database = new PDO(/* your connection details here */);
$statement = $database->prepare("
SELECT DISTINCT date
FROM holiday
WHERE date >= :start_date
ORDER BY date ASC;
");
$statement->bindValue(':start_date', $start_date);
$statement->execute();
return $statement->fetchAll(PDO::FETCH_COLUMN);
}
假设holidays
表如您的问题所示存在,您可以组合这些函数来获取截止日期:
$holidays = getHolidays('2017-12-21');
var_dump($holidays);
$deadline_end_date = getDeadline('2017-12-21', 5, $holidays);
var_dump($deadline_end_date);
给出输出:
string(10) "2017-12-28"
string(10) "2018-01-01"
array(6) {
[0]=>
string(10) "2017-12-22"
[1]=>
string(10) "2017-12-26"
[2]=>
string(10) "2017-12-27"
[3]=>
string(10) "2018-01-01"
[4]=>
string(10) "2018-01-02"
[5]=>
string(10) "2018-01-03"
}
string(10) "2018-01-05"
您的应用程序中有数据库吗?您好,欢迎使用Stack Overflow!在您的示例中,您提供了大量代码。请尝试将其简化为一个。您的问题越简化,我们就越容易帮助您,尽管目前情况下,您已经为我们提供了大量代码,让我们进行筛选,以了解发生了什么。同样,请请解释您所说的“未能获得良好结果”是什么意思。您是否收到错误消息?输出错误?请与我们分享您收到的输出,这将使错误更容易找到。strotime(日期(“Y-m-d”,strotime($startDate+”)(1+getWorkingDays($startDate,$endDate,$holidays))。“天”))回归2018-01-02这是一个完美的假期!你是最棒的,我试了好几天!完美,完美!