Programming/PHP

PHP 주말,공휴일 제외한 영업일(날짜) 구하기

고고마코드 2021. 12. 23. 01:17
반응형

공휴일 계산은 공공데이터포털의 한국천문연구원_특일 정보 API를 사용합니다.


공휴일 구하기

API 인증키 받기

공휴일을 구하기 위해 공공데이터포털의 한국천문연구원_특일 정보 API를 사용했다.

해당 API를 사용하기 위해서는 아래 링크에서 활용 신청을 해야 한다.

한국천문연구원_특일 정보 | 공공데이터포털 (data.go.kr)

활용 신청을 하면 하단에 일반 인증키를 받게 됩니다.

환경 또는 호출 조건에 따라 두 인증키를 적용하면서 구동되는 키를 사용하라고 합니다.

저는 일반 인증키(Encoding)을 사용했습니다.

API로 공휴일 데이터 가져오기

function getHoliday($year,$month) {
    $key = "your API Key"; 
    $param = 'ServiceKey='.$key;
    $param .= '&solYear='.$year;
    if($month > "") { $param .= '&solMonth='.sprintf("%02d",$month); }
    $param .= '&numOfRows=9999';

    $reqUrl = "http://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/getRestDeInfo?".$param;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $reqUrl);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
    $response = curl_exec($ch);
    curl_close($ch);

    $xml = simplexml_load_string($response);
    $json = json_encode($xml);
    $data = json_decode($json,true);

    return $data;
}

API로 공휴일 데이터를 가져와 json 으로 변환하는 코드입니다.

your API Key 부분에 부여받은 API 인증키를 입력하면 됩니다.

가공한 공휴일 데이터 활용하기

위에서 가공한(json) 공휴일 데이터로 직접적으로 바로 활용하거나 DB에 활용할 수 있습니다.

$currentYear = date('Y');
$data = getHoliday($currentYear,"");
foreach($data['body']['items'] as $items) {
    foreach($items as $item) {
        echo "locdate: ". $item['locdate']. ", dateName: ". $item['dateName']. "<br>";
        #활용할 코드 작성
    }
}

년도만 있다면 전체 년도에 해당하는 공휴일 데이터를 가져오고

월까지 있다면 해당 월에 해당하는 공휴일 데이터만 가져옵니다.

예) year = 2021, month = "" -> 2021년의 공휴일 데이터를 전부 가져옵니다.

예) year = 2021, month = 3 -> 2021년 3월의 공휴일 데이터만 가져옵니다.

지정한 날짜부터 일정 기간 이후의 날짜 구하기, 주말 제외(영업일)

주말 제외한 날짜 구하기

// 날짜 간격 - 주말,특정일 제외
function calcDayOffDate($date, $diff) { 
    $sign = $diff < 0 ? "-" : "+";

    do { 
        $date = date("Y-m-d", strtotime("{$sign}1 days", strtotime($date))); 
        if ((date("w", strtotime($date)) != 0 && date("w", strtotime($date)) != 6)) { 
            $diff = $sign === "-" ? $diff + 1 : $diff - 1;
        } 
    } while ($diff != 0); 

    return $date; 
}

calcDayOffDate(date("Y-m-d H:i:s"), 10); #현재일로부터 영업일 10일 뒤의 날짜를 구한다.

날짜로부터 특정일 이후 또는 이전을 계산하는 함수이다.

위 코드를 예를 들면 아래 같은 결과가 나온다.

ex) date("Y-m-d H:i:s") : 2021-12-23 01:07:26

ex) calcDayOffDate(date("Y-m-d H:i:s"), 10) : 2022-01-06

주말/공휴일 제외한 날짜 구하기

공휴일 가져오기 함수를 활용하면 주말 제외하기 함수를 살짝 수정하여 주말/공휴일 제외한 날짜를 구할 수 있습니다.

// 날짜 간격 - 주말,특정일 제외
function calcDayOffDate($date, $diff, $holidayAry="") { 
    $sign = $diff < 0 ? "-" : "+";

    do { 
        $date = date("Y-m-d", strtotime("{$sign}1 days", strtotime($date))); 
        if ((date("w", strtotime($date)) != 0 && date("w", strtotime($date)) != 6) && !in_array($date, $holidayAry) ) { 
            $diff = $sign === "-" ? $diff + 1 : $diff - 1;
        } 
    } while ($diff != 0); 

    return $date; 
}
  • 우선 $holidayAry 라는 변수를 추가합니다. (공휴일 정보를 담는 array입니다)
$holiday = array();
foreach($result as $row) {
    array_push($holiday, date("Y-m-d", strtotime($row['locdate'])));
}
$predictionDate = calcDayOffDate(date("Y-m-d H:i:s"), $predictionDays, $holiday);

공휴일 함수 + 주말 제외하기 함수를 활용해 주말/공휴일을 모두 제외한 영업일 계산이 완료되었습니다.

전체 코드

function getHoliday($year,$month) {
    $key = "your API Key"; 
    $param = 'ServiceKey='.$key;
    $param .= '&solYear='.$year;
    if($month > "") { $param .= '&solMonth='.sprintf("%02d",$month); }
    $param .= '&numOfRows=9999';

    $reqUrl = "http://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/getRestDeInfo?".$param;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $reqUrl);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
    $response = curl_exec($ch);
    curl_close($ch);

    $xml = simplexml_load_string($response);
    $json = json_encode($xml);
    $data = json_decode($json,true);

    return $data;
}

$currentYear = date('Y');
$data = getHoliday($currentYear,"");
foreach($data['body']['items'] as $items) {
    foreach($items as $item) {
        echo "locdate: ". $item['locdate']. ", dateName: ". $item['dateName']. "<br>";
        #활용할 코드 작성
    }
}

// 날짜 간격 - 주말,특정일 제외
function calcDayOffDate($date, $diff, $holidayAry="") { 
    $sign = $diff < 0 ? "-" : "+";

    do { 
        $date = date("Y-m-d", strtotime("{$sign}1 days", strtotime($date))); 
        if ((date("w", strtotime($date)) != 0 && date("w", strtotime($date)) != 6) && !in_array($date, $holidayAry) ) { 
            $diff = $sign === "-" ? $diff + 1 : $diff - 1;
        } 
    } while ($diff != 0); 

    return $date; 
}

$holiday = array();
foreach($result as $row) {
    array_push($holiday, date("Y-m-d", strtotime($row['locdate'])));
}
$predictionDate = calcDayOffDate(date("Y-m-d H:i:s"), $predictionDays, $holiday);

반응형