ผมเขียนฟังก์ชั่น วิธีหาวันหยุดภายในเดือน ตอนที่ 1 ไว้ที่ http://www.select2web.com/php/php-working-day.html ฟังก์ชั่นในภาค 1 นั้นจะยึดเอาว่าวันเสาร์-อาทิตย์เท่านั้น เป็นวันหยุด แต่ความเป็นจริงของการทำงาน ในแต่ละเดือนจะมีวันหยุดพิเศษเพิ่มเติม อย่าง วันสงกรานต์,วันแรงงาน,วันพ่อ,วันแม่,วันปีใหม่ และอีกหลายวันที่เป็นวันหยุดนอกเหนือเสาร์-อาทิตย์

ครานี้ผมจะต่อยอดฟังก์ชั่นหาวันหยุดเดิม ให้มันซัพพอร์ตวันหยุดพิเศษเข้าไปด้วย ถ้ายังไม่ได้อ่านตอนที่ 1 ให้ไปอ่านเสียก่อนนะครับ ลิ้งก์ด้านบนนั่นแหละครับ ถ้าไม่อ่านก่อนเดี๋ยวอารมณ์มันจะไม่ต่อเนื่อง ต่อครับ

function WorkingDays($year, $month, $day, $extras=array()) {
    if (!$year)
        $year = date('Y');
    if (!$month)
        $month = date('m');
    if (!$day)
        $day = date('d');
 
 
    //create a start and an end datetime value based on the input year 
    $startdate = strtotime($year . '-' . $month . '-01');
    $enddate = strtotime($year . '-' . $month . '-' . $day);
    $currentdate = $startdate;
 
    while ($currentdate <= $enddate) {
        //if you encounter a Saturday or Sunday, remove from the total days count
        if (!((date('D', $currentdate) == 'Sat') || (date('D', $currentdate) == 'Sun') || in_array(date('d', $currentdate), $extras))) {
            $return = $return + 1;
        }
        $currentdate = strtotime('+1 day', $currentdate);
    } //end date walk loop
    //return the number of working days
    return $return;
}
 
$stop = array(13,14,15);
 
echo WorkingDays(2011, 4, 30, $stop);

ตอนแรกทำการตรวจสอบว่าได้ส่งวันเดือนปีเข้ามาในฟังก์ชั่นหรือเปล่า ถ้าไม่ได้ส่งเข้ามาก็ให้ดีฟอลต์ไว้ที่วันปัจจุบัน

    if (!$year)
        $year = date('Y');
    if (!$month)
        $month = date('m');
    if (!$day)
        $day = date('d');

หาวันแรกของเดือน ซึ่งมันจะเป็นวันที่ 1 เสมอ กำหนดให้เป็นตัวเลขวินาที (เพื่อที่จะนำไปเปรียบเทียบกันได้ง่ายๆ) และหาวันสิ้นสุด

    $startdate = strtotime($year . '-' . $month . '-01');
    $enddate = strtotime($year . '-' . $month . '-' . $day);

วนลูปจากวันแรกจนไปถึงวันสุดท้าย ภายในลูปทำการตรวจสอบว่าเป็นวันเสาร์-อาทิตย์ และอยู่ในลิสต์ของวันหยุดพิเศษ หรือไม่ ถ้าไม่ใช่ก็ให้ +วันทำงานเข้าไปอีก 1

    while ($currentdate <= $enddate) {
        //if you encounter a Saturday or Sunday, remove from the total days count
        if (!((date('D', $currentdate) == 'Sat') || (date('D', $currentdate) == 'Sun') || in_array(date('d', $currentdate), $extras))) {
            $return = $return + 1;
        }
        $currentdate = strtotime('+1 day', $currentdate);
    } //end date walk loop

ตอนนี้ฟังก์ชั่นเรานอกจากจะยึดวันเสาร์-อาทิตย์ เป็นวันหยุดแล้ว ยังสามารถนับข้ามวันหยุดพิเศษที่เรากำหนดอีกด้วย

คำสั่ง in_array() นั้นใช้สำหรับตรวจสอบว่าค่านั้นๆ มีอยู่ในอะเรย์หรือไม่ ถ้ามีจะคืนค่ากลับมาเป็น true ถ้าไม่มีจะคืนค่ากลับมาเป็น false