Рассчитать рабочие дни - PullRequest
       111

Рассчитать рабочие дни

98 голосов
/ 03 декабря 2008

Мне нужен метод для добавления «рабочих дней» в PHP. Например, пятница 12/5 + 3 рабочих дня = среда 12/10.

Как минимум, мне нужен код для понимания выходных, но в идеале он должен учитывать и федеральные праздники США. Я уверен, что мог бы найти решение, используя грубую силу, если это необходимо, но я надеюсь, что есть более элегантный подход. Кто-нибудь? * * 1003

Спасибо.

Ответы [ 34 ]

0 голосов
/ 09 июня 2013

Только что закончил писать API, который можно использовать для манипулирования рабочими днями (ни одно из этих решений не сработало для моей ситуации :-); ссылка на него здесь на случай, если кто-то еще посчитает это полезным.

~ Нейт

PHP класс для расчета рабочих дней

0 голосов
/ 10 июля 2013

Спасибо Бобине, МакГрэйму, Тони, Джеймсу Пасте и нескольким другим, которые разместили здесь. Я написал свою собственную функцию для добавления рабочих дней к дате, но изменил ее с помощью некоторого кода, который я нашел здесь. Это будет обрабатывать дату начала на выходные / праздничные дни. Это также будет обрабатывать рабочие часы. Я добавил несколько комментариев и разбил код, чтобы его было легче читать.

<?php
function count_business_days($date, $days, $holidays) {
    $date = strtotime($date);

    for ($i = 1; $i <= intval($days); $i++) { //Loops each day count

        //First, find the next available weekday because this might be a weekend/holiday
        while (date('N', $date) >= 6 || in_array(date('Y-m-d', $date), $holidays)){
            $date = strtotime(date('Y-m-d',$date).' +1 day');
        }

        //Now that we know we have a business day, add 1 day to it
        $date = strtotime(date('Y-m-d',$date).' +1 day');

        //If this day that was previously added falls on a weekend/holiday, then find the next business day
        while (date('N', $date) >= 6 || in_array(date('Y-m-d', $date), $holidays)){
            $date = strtotime(date('Y-m-d',$date).' +1 day');
        }
    }
    return date('Y-m-d', $date);
}

//Also add in the code from Tony and James Pasta to handle holidays...

function getNationalAmericanHolidays($year) {
$bankHolidays = array(
    'New Years Day' => $year . "-01-01",
    'Martin Luther King Jr Birthday' => "". date("Y-m-d",strtotime("third Monday of January " . $year) ),
    'Washingtons Birthday' => "". date("Y-m-d",strtotime("third Monday of February " . $year) ),
    'Memorial Day' => "". date("Y-m-d",strtotime("last Monday of May " . $year) ),
    'Independance Day' => $year . "-07-04",
    'Labor Day' => "". date("Y-m-d",strtotime("first Monday of September " . $year) ),
    'Columbus Day' => "". date("Y-m-d",strtotime("second Monday of October " . $year) ),
    'Veterans Day' => $year . "-11-11",
    'Thanksgiving Day' => "". date("Y-m-d",strtotime("fourth Thursday of November " . $year) ),
    'Christmas Day' => $year . "-12-25"
);
return $bankHolidays;

}

//Now to call it... since we're working with business days, we should
//also be working with business hours so check if it's after 5 PM
//and go to the next day if necessary.

//Go to next day if after 5 pm (5 pm = 17)
if (date(G) >= 17) {
    $start_date = date("Y-m-d", strtotime("+ 1 day")); //Tomorrow
} else {
    $start_date = date("Y-m-d"); //Today
}

//Get the holidays for the current year and also for the next year
$this_year = getNationalAmericanHolidays(date('Y'));
$next_year = getNationalAmericanHolidays(date('Y', strtotime("+12 months")));
$holidays = array_merge($this_year, $next_year);

//The number of days to count
$days_count = 10;

echo count_business_days($start_date, $days_count, $holidays);

?>
0 голосов
/ 12 мая 2013

https://github.com/Arbitr108/useful_php Вот класс, который может рассчитывать рабочие дни в календаре. Поэтому после оценки просто добавьте календарный период к нужной вам дате

0 голосов
/ 02 апреля 2010

функция get_business_days_forward_from_date ($ num_days, $ start_date = '', $ rtn_fmt = 'Y-m-d') {

// $start_date will default to today    

if ($start_date=='') { $start_date = date("Y-m-d"); }

$business_day_ct = 0;

$max_days = 10000 + $num_days;  // to avoid any possibility of an infinite loop


// define holidays, this currently only goes to 2012 because, well, you know... ;-)
// if the world is still here after that, you can find more at
// http://www.opm.gov/Operating_Status_Schedules/fedhol/2013.asp
// always add holidays in order, because the iteration will stop when the holiday is > date being tested

$fed_holidays=array(
    "2010-01-01",
    "2010-01-18",
    "2010-02-15",
    "2010-05-31",
    "2010-07-05",
    "2010-09-06",
    "2010-10-11",
    "2010-11-11",
    "2010-11-25",
    "2010-12-24",

    "2010-12-31",
    "2011-01-17",
    "2011-02-21",
    "2011-05-30",
    "2011-07-04",
    "2011-09-05",
    "2011-10-10",
    "2011-11-11",
    "2011-11-24",
    "2011-12-26",

    "2012-01-02",
    "2012-01-16",
    "2012-02-20",
    "2012-05-28",
    "2012-07-04",
    "2012-09-03",
    "2012-10-08",
    "2012-11-12",
    "2012-11-22",
    "2012-12-25",
    );

$curr_date_ymd = date('Y-m-d', strtotime($start_date));    

for ($x=1;$x<$max_days;$x++)
{
    if (intval($num_days)==intval($business_day_ct)) { return(date($rtn_fmt, strtotime($curr_date_ymd))); }  // date found - return

    // get next day to check

    $curr_date_ymd = date('Y-m-d', (strtotime($start_date)+($x * 86400)));   // add 1 day to the current date

    $is_business_day = 1;

    // check if this is a weekend   1 (for Monday) through 7 (for Sunday)

    if ( intval(date("N",strtotime($curr_date_ymd))) > 5) { $is_business_day = 0; }

    //check for holiday
    foreach($fed_holidays as $holiday)
    {
        if (strtotime($holiday)==strtotime($curr_date_ymd))  // holiday found
        {
            $is_business_day = 0;
            break 1;
        }

        if (strtotime($holiday)>strtotime($curr_date_ymd)) { break 1; }  // past date, stop searching (always add holidays in order)


    }

    $business_day_ct = $business_day_ct + $is_business_day;  // increment if this is a business day

} 

// if we get here, you are hosed
return ("ERROR");

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...