2017-12-21 13 views
0

締め切り日は5日ですが、ルールを作成しようとしています+休業日(週末または休日)ごとに1日。また思い出させて、次の表の休日その最終日は、週末や休日...締め切りは5日です休業日(週末または休日)ごとに+1日を追加する必要があります

マイ表ホリデーことができない場合

enter image description here

私はとにかくそれを試してみたが、私は良いを取得することはできませんその結果、あなたが休日のオプションの配列で、開始日に営業日の数を追加することができDateTimeDateIntervalを使用して

//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; 
} 
+0

は、あなたのアプリケーションでデータベースを持っていますか? –

+1

こんにちは、ようこそ、スタックオーバーフローへようこそ!あなたの例では、たくさんのコードを提供しています。それを[MCVE]に単純化しよう。あなたの質問を簡素化すればするほど、私たちはあなたの手助けをしやすくなりますが、何が起きているのか把握しようとするための多くのコードを私たちに与えてくれます。また、「良い結果を得ることができなかった」ということを説明してください。エラーメッセージが表示されますか?間違った出力?どんな出力を得ているのか分かち合うと、エラーを見つけやすくなります。 –

+0

strtotime(日付( "Ymd"、strtotime( "$ startDate +"。(1 + getWorkingDays($ startDate、$ endDate、$ holidays))。 "days"))) 今日の2018-01-02日を返しますお休みです –

答えて

0

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 

は、出力を与える:あなたの休日は、mysqlのに格納されていたよう

string(10) "2017-12-28" 
string(10) "2018-01-01" 

、あなたは、単一のクエリでそれらを抽出するために、このような関数を使用できます。

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テーブルはあなたのように存在しますestion、あなたは期限の日付を取得するために、これらの機能を組み合わせることができます。

$holidays = getHolidays('2017-12-21'); 
var_dump($holidays); 
$deadline_end_date = getDeadline('2017-12-21', 5, $holidays); 
var_dump($deadline_end_date); 

は、出力を提供します:

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" 
+0

パーフェクト!あなたは最高でした、私は数日間試しました!パーフェクト、パーフェクト! –

関連する問題