<!--//  planner_standard용 function 전체 : function_calendar_month.php 소스 -->

<?php
    /**
     * @file   function_calendar.php
     * @author keysung Chung
     * @brief  calender function
     **/

//--------------------------------------------------------------------------------
    /**
     * @function: fn_leapmonth($pYear)
     * @return:   boolean
     * @brief:    그해의 윤달 여부 (윤년)
     **/
function fn_leapmonth($pYear){

    /*연도를 100으로 나눠떨어지지 않으면서 4로 나누어 떨어지면 윤달있음.
     *또는
     *연도를 100으로 나눠떨어지는 경우는 연도를 400으로 나눠떨어지면 윤달있음.
    **/

    if (($pYear % 100 <> 0 && $pYear % 4 == 0) or $pYear % 400 == 0) {
        $fn_leapmonth = true;
    }
    else {
        $fn_leapmonth = false;
    }
    return $fn_leapmonth;

    // 또는 단순히 date()를 이용 하거나....("L" : 윤년여부 윤년엔 1, 그 외엔 0)
    // return date("L", mktime(0, 0, 0, $pMonth, 1, $pYear));
}

//--------------------------------------------------------------------------------

    /**
     * @function: fn_monthcount($pYear,$pMonth)
     * @return  : integer
     * @brief:    해당월의 마지막 일을 반환한다
     **/
function fn_monthcount($pYear,$pMonth) {
    $aMonthNum = explode("-","31-0-31-30-31-30-31-31-30-31-30-31-");
     //2월달은 예외

    if (fn_leapmonth($pYear)) {
        $aMonthNum[1] = 29;
    }
    else {
        $aMonthNum[1] = 28;
    }
//    return $aMonthNum;
    return $aMonthNum[$pMonth-1];

    // 또는 단순히 date()를 이용 하거나....("t" : 주어진 월의 일수)
    // return date("t", mktime(0, 0, 0, $pMonth, 1, $pYear));
}

//--------------------------------------------------------------------------------

    /**
     * @function: fn_firstweek($pYear,$pMonth)
     * @return  : integer
     * @brief:    해당년/월의 첫번째일의 위치를 반환 ("w" : 0=일요일, 6=토요일)
     **/
function fn_firstweek($pYear,$pMonth) {
    return date("w", mktime(0, 0, 0,$pMonth, 1, $pYear));
}

//--------------------------------------------------------------------------------

    /**
     * @function: fn_nowweek($pYear,$pMonth,$pDay)
     * @return  : integer
     * @brief:    해당년/월/일의 요일 위치를 반환 ("w" : 0=일요일, 6=토요일)
     **/
function fn_nowweek($pYear,$pMonth,$pDay) {
    return date("w", mktime(0, 0, 0,$pMonth, $pDay, $pYear));
}

//------------------------------------------------------------------------------
    /**
     * @function: fn_lastweek($pYear,$pMonth)
     * @return  : integer
     * @brief:    해당년/월의 마지막날 위치를 반환  ("w" : 0=일요일, 6=토요일)
     **/
function fn_lastweek($pYear,$pMonth) {
    return date("w", mktime(0, 0, 0,$pMonth, fn_monthcount($pYear,$pMonth), $pYear));
}
//-----------------------------------------------------------------------------------
    /**
     * @function: fn_blankweekfirst($pYear,$pMonth)
     * @return  : integer
     * @brief:    해당년/월의 첫번째주 빈값을 구한다.
     * @brief:    해당 년/월의 일수시작이 수요일(3) 이라면 일(0)/월(1)/화(2) 즉 3개는 빈값이다.
     **/
function fn_blankweekfirst($pYear,$pMonth) {
    return fn_firstweek($pYear,$pMonth);
}

//--------------------------------------------------------------------------------------

    /**
     * @function: fn_blankweeklast($pYear,$pMonth)
     * @return  : integer
     * @brief:    해당년/월의 마지막주 빈값을 구한다.
     * @brief:    해당 년/월의 일수끝이 목요일(4) 이라면 금(5)/토(6) 즉 2개는 빈값이다.
     **/
function fn_blankweeklast($pYear,$pMonth) {
    return 6 - fn_lastweek($pYear,$pMonth);
}

//--------------------------------------------------------------------------------------

    /**
     * @function: fn_weekcountofmonth($pYear,$pMonth,$pDay)
     * @return  : integer
     * @brief:    해당 년/월/일이 당월 몇번째 주에 해당 되는지를 구한다.
     * @brief:    해당 년/월/일이 당월 2번째 주에 포함된다면 2를 반환.
     **/
function fn_weekcountofmonth($pYear,$pMonth,$pDay) {
    $wrkday = $pDay + date("w", mktime(0, 0, 0,$pMonth, 1, $pYear)); //1일의 요일번호(일=0, 토=6)
    $weekcount = floor($wrkday/7);  //소숫점이하 절사
    if ( $wrkday % 7 > 0 ) {
        $weekcount = $weekcount + 1;
    }
    return $weekcount;      // n번째 주
}

//--------------------------------------------------------------------------------------

    /**
     * @function: fn_weekdaycountofmonth($pYear,$pMonth,$pDay)
     * @return  : integer
     * @brief:    해당 년/월/일의 요일이 당월 몇번째 요일에 해당되는지 구한다.
     * @brief:    해당 년/월/일의 요일이 당월 2번째요일 이면 2를 반환.
     **/
function fn_weekdaycountofmonth($pYear,$pMonth,$pDay) {
    $k=0;       // 카운터
    $pYoil = date("w", mktime(0, 0, 0,$pMonth, $pDay, $pYear)); //해당일의 요일번호(일=0, 토=6)

    for ($i=1; $i<=$pDay; $i++) {                               // 1일 부터 말일까지 수행
        $wrk1 = date("w", mktime(0, 0, 0,$pMonth, $i, $pYear));
        if ($wrk1 == $pYoil) {              // 요일 일치
            $k=$k+1;
        }
    }
    return $k;      // n번째 요일
}

//--------------------------------------------------------------------------------------

    /**
     * @function: fn_nsweekday($pYear, $pMonth, $pCount, $pYoil)
     * @return  : string
     * @brief:    해당년/월 n번째 x요일의 일자를 구한다
     * @brief:     pCount: 숫자, pYoil: 숫자 (일요일(0) ... 토요일(6)).
     **/
function fn_nsweekday($pYear, $pMonth, $pCount, $pYoil) {
    $k=0;       // 카운터
    $j = date("t", mktime(0, 0, 0, $pMonth, 1, $pYear));    // 해당월의 날자수(말일) 값
    for ($i=1; $i<=$j; $i++) {                              // 1일 부터 말일까지 수행
        $wrk1 = date("w", mktime(0, 0, 0,$pMonth, $i, $pYear));
        if ($wrk1 == $pYoil) {              // 요일 일치
            $k=$k+1;
            if ($k == $pCount) {            // 횟수 일치
                $wrkYmd =date("Y-n-j", mktime(0, 0, 0,$pMonth, $i, $pYear));
            }
        }
    }
    return $wrkYmd;
}

//--------------------------------------------------------------------------------------

    /**
     * @function: fn_nsweeknsweekday($pYear, $pMonth, $pCount, $pYoil)
     * @return  : string
     * @brief:    해당년/월 n번째 주 x요일의 일자를 구한다
     * @brief:    pCount: 숫자, pYoil: 숫자 (일요일(0) ... 토요일(6)).
     **/
function fn_nsweeknsweekday($pYear, $pMonth, $pCount, $pYoil) {
    $k=1;       //  주 카운터
    $j = date("t", mktime(0, 0, 0, $pMonth, 1, $pYear));    // 해당월의 날자수(말일) 값
    for ($i=1; $i<=$j; $i++) {                              // 1일 부터 말일까지 수행
        $wrk1 = date("w", mktime(0, 0, 0,$pMonth, $i, $pYear)); // 요일
        if ($i != 1 && $wrk1==0) {         // 첫날이 아니면서 일요일 이면 주 카운터 증가
            $k = $k + 1;
        }
        if ($wrk1 == $pYoil) {              // 요일 일치
            if ($k == $pCount) {            // 횟수 일치
                $wrkYmd =date("Y-n-j", mktime(0, 0, 0,$pMonth, $i, $pYear));
            }
        }
    }
    return $wrkYmd;
}

//--------------------------------------------------------------------------------------

    /**
     * @function: fn_weekdaycountofmonth_end($pYear,$pMonth,$pDay)
     * @return  : integer
     * @brief:    해당 년/월/일의 요일이 당월 끝에서 몇번째 요일에 해당되는지 요일차를 구한다.
     * @brief:    해당 년/월/일의 요일이 당월 끝에서 2번째요일 이면 2를 반환.
     **/
function fn_weekdaycountofmonth_end($pYear,$pMonth,$pDay) {
    $k=0;       // 카운터
    $pYoil = date("w", mktime(0, 0, 0,$pMonth, $pDay, $pYear)); //해당일의 요일번호(일=0, 토=6)
    $j = date("t", mktime(0, 0, 0, $pMonth, 1, $pYear));    // 해당월의 날자수(말일) 값
    for ($i=$j; $i>=$pDay; $i--) {                          // 말일 부터 당일까지 수행
        $wrk1 = date("w", mktime(0, 0, 0,$pMonth, $i, $pYear));
        if ($wrk1 == $pYoil) {              // 요일 일치
            $k=$k+1;
        }
    }
    return $k;      // n번째 요일
}

//--------------------------------------------------------------------------------------

    /**
     * @function: fn_nslastweekday($pYear, $pMonth, $pCount, $pYoil)
     * @return  : string
     * @brief:    해당년/월 끝에서 n번째 x요일의 일자를 구한다
     * @brief:     pCount: 숫자, pYoil: 숫자 (일요일(0) ... 토요일(6)).
     **/
function fn_nslastweekday($pYear, $pMonth, $pCount, $pYoil) {
    $k=0;       //  주 카운터
    $j = date("t", mktime(0, 0, 0, $pMonth, 1, $pYear));    // 해당월의 날자수(말일) 값
    for ($i=$j; $i>=1; $i--) {                              // 말일 부터 1일까지 수행
        $wrk1 = date("w", mktime(0, 0, 0,$pMonth, $i, $pYear)); // 요일
        if ($wrk1 == $pYoil) {              // 요일 일치
            $k = $k + 1;
            if ($k == $pCount) {            // 횟수 일치
                $wrkYmd =date("Y-n-j", mktime(0, 0, 0,$pMonth, $i, $pYear));
            }
        }
    }
    return $wrkYmd;
}

//--------------------------------------------------------------------------------
    /**
     * @function: fn_CalMain($pYear,$pMonth)
     * @return  : array
     * @brief:    주어진 년/월의 달력을 만든다.
     * @brief:     2차원배열을 사용하여 틀을 만든다.
     * @brief:     가로(1주)는 무조건 7이 되므로 세로값만 알면 된다.
     * @brief:     빈칸은 null 값으로한다
     * @brief:     형태예제
     * @brief:     |일|월|화|수|목|금|토|
     * @brief:     | n| n| n| n| n| n| 1|
     * @brief:     | 2| 3| 4| 5| 6| 7| 8|
     * @brief:     | 9|10|11|12|13|14|15|
     * @brief:     |16|17|18|19|20|21|22|
     * @brief:     |23|24|25|26|27|28|29|
     * @brief:     |30|31| n| n| n| n| n|
     **/
function fn_CalMain($pYear,$pMonth) {

    //$aCal[][];       //달력의 틀을 위한 2차원배열
    //$intVertical;  //세로줄값
    //$intWeekcnt;   //주일수
    //$i;
    //$j;
    //$k;            //루프전체 합
    //$intDay;       //일수 값

    //초기값 셋팅
    $k=0;
    $intDay=1;      //일

    //세로값얻는 방법 (그달의 일수 + 첫째주빈값 + 마지막주빈값)/7=세로값
    $intVertical = (fn_monthcount($pYear,$pMonth)+fn_blankweekfirst($pYear,$pMonth)+fn_blankweeklast($pYear,$pMonth))/7;
    $intWeekcnt = 7;

    //배열셋팅
    // array[세로사이즈][가로사이즈]
    $aCal[$intVertical][$intWeekcnt];

    //배열에 값 삽입
    for ($i=0; $i<$intVertical; $i++ ) {
        for ($j=0; $j<$intWeekcnt; $j++ ){
            $k=$k+1;
            //k의값이 첫번째주 빈값보다 작거나 같을경우는 *을 삽입
            if ($k<=fn_blankweekfirst($pYear,$pMonth)) {
                $aCal[$i][$j] = "*";
            }
            //k의값이 첫번째주빈값이상이며, 일자가 해당월의 마지막 일자 값과 작거나같을경우는 일수를 삽입
            else {
                if ($intDay<=fn_monthcount($pYear,$pMonth)) {
                $aCal[$i][$j] = $intDay;
                $intDay = $intDay+1;
                }

                //이외의 값은 *로 채운다
                else {
                    $aCal[$i][$j] = "*";
                }
            }
        }
    }
    return $aCal;
}

//--------------------------------------------------------------------------------------

    /**
     * @function: fn_smallcalendar()
     * @return  : string
     * @brief:    소형 당월 칼런다 HTML코드 출력
     * @brief:
     **/

function fn_smallcalendar(){
    $year = date("Y");
    $month = date("n");
    $day = date("d");
    $day_max = date("t",mktime(0,0,0,$month,1,$year));
    $week_start = date("w",mktime(0,0,0,$month,1,$year));
    $i = 0;
    $j = 0;
    $html = "<div class='calendar_box'><div class='calendar_title B'>".sprintf("%d-%02d-%02d",$year,$month,$day)."</div>";
    while ($j<$day_max){
        if ($i<$week_start) {
            $html .= "<div class='calendar_text'>·</div>";
        } else {
            if ($i%7==0) $font_color = " RED";
            else if ($i%7==6) $font_color = " BLUE";
            else $font_color = "";
            if ($day == ($j+1)) $font_weight = " B"; else $font_weight = "";
            $html .= "<div class='calendar_text$font_color$font_weight'>" . ($j+1) . "</div>";
            $j ++;
        }
        $i ++;
    }
    while ($i%7!==0){
        $html .= "<div class='calendar_text'>·</div>";
        $i ++;
    }
    $html .= "<div class='calendar_tail'></div></div>";
    return $html;
}


//--------------------------------------------------------------------------------------
    /**
     * @function: fn_sunlunar_data()
     * @return  : string(13자리-13자리-... 170개)
     * @brief:    음력-양력 변환위한 자료
     **/
function fn_sunlunar_data() {
return " ";   //1881-2050
}

//------------------------------------------------------------------------

    /**
     * @function: fn_lun2sol($pYear,$pMonth,$pDay)
     * @return  : string(yyyy-mm-dd-요일)
     * @brief:    음력을 양력으로 변환하는 함수
     **/
function fn_lun2sol($pYear,$pMonth,$pDay) {
$getYEAR = (int)$pYear;
$getMONTH = (int)$pMonth;
$getDAY = (int)$pDay;
//$getYEAR = (int)substr($yyyymmdd,0,4);
//$getMONTH = (int)substr($yyyymmdd,4,2);
//$getDAY = (int)substr($yyyymmdd,6,2);

$arrayDATASTR = fn_sunlunar_data();
$arrayDATA = explode("-",$arrayDATASTR);

$arrayLDAYSTR="31-0-31-30-31-30-31-31-30-31-30-31";
$arrayLDAY = explode("-",$arrayLDAYSTR);

$arrayYUKSTR="갑-을-병-정-무-기-경-신-임-계";
$arrayYUK = explode("-",$arrayYUKSTR);

$arrayGAPSTR="자-축-인-묘-진-사-오-미-신-유-술-해";
$arrayGAP = explode("-",$arrayGAPSTR);

$arrayDDISTR="쥐-소-호랑이-토끼-용-뱀-말-양-원숭이-닭-개-돼지";
$arrayDDI = explode("-",$arrayDDISTR);

$arrayWEEKSTR="일-월-화-수-목-금-토";
$arrayWEEK = explode("-",$arrayWEEKSTR);

if ($getYEAR <= 1881 || $getYEAR >= 2050) { //년수가 해당일자를 넘는 경우
$YunMonthFlag = 0;
return false; //년도 범위가 벗어남..
}
if ($getMONTH > 12) { // 달수가 13이 넘는 경우
$YunMonthFlag = 0;
return false; //달수 범위가 벗어남..
}
$m1 = $getYEAR - 1881;
if (substr($arrayDATA[$m1],12,1) == 0) { // 윤달이 없는 해임
$YunMonthFlag = 0;
} else {
if (substr($arrayDATA[$m1],$getMONTH, 1) > 2) {
$YunMonthFlag = 1;
} else {
$YunMonthFlag = 0;
}
}
//-------------
$m1 = -1;
$td = 0;

if ($getYEAR > 1881 && $getYEAR < 2050) {
$m1 = $getYEAR - 1882;
for ($i=0;$i<=$m1;$i++) {
for ($j=0;$j<=12;$j++) {
$td = $td + (substr($arrayDATA[$i],$j,1));
}
if (substr($arrayDATA[$i],12,1) == 0) {
$td = $td + 336;
} else {
$td = $td + 362;
}
}
} else {
$gf_lun2sol = 0;
}

$m1++;
$n2 = $getMONTH - 1;
$m2 = -1;

while(1) {
$m2++;
if (substr($arrayDATA[$m1], $m2, 1) > 2) {
$td = $td + 26 + (substr($arrayDATA[$m1], $m2, 1));
$n2++;
} else {
if ($m2 == $n2) {
if ($gf_yun) {
$td = $td + 28 + (substr($arrayDATA[$m1], $m2, 1));
}
break;
} else {
$td = $td + 28 + (substr($arrayDATA[$m1], $m2, 1));
}
}
}

$td = $td + $getDAY + 29;
$m1 = 1880;
while(1) {
$m1++;
if ($m1 % 400 == 0 || $m1 % 100 != 0 && $m1 % 4 == 0) {
$leap = 1;
} else {
$leap = 0;
}

if ($leap == 1) {
$m2 = 366;
} else {
$m2 = 365;
}

if ($td < $m2) break;

$td = $td - $m2;
}
$syear = $m1;
$arrayLDAY[1] = $m2 - 337;

$m1 = 0;

while(1) {
$m1++;
if ($td <= $arrayLDAY[$m1-1]) {
break;
}
$td = $td - $arrayLDAY[$m1-1];
}
$smonth = $m1;
$sday = $td;
$y = $syear - 1;
$td = intval($y*365) + intval($y/4) - intval($y/100) + intval($y/400);

if ($syear % 400 == 0 || $syear % 100 != 0 && $syear % 4 == 0) {
$leap = 1;
} else {
$leap = 0;
}

if ($leap == 1) {
$arrayLDAY[1] = 29;
} else {
$arrayLDAY[1] = 28;
}
for ($i=0;$i<=$smonth-2;$i++) {
$td = $td + $arrayLDAY[$i];
}
$td = $td + $sday;
$w = $td % 7;

$sweek = $arrayWEEK[$w];
$gf_lun2sol = 1;

return($syear."-".$smonth."-".$sday."-".$sweek."-".$YunMonthFlag);
}

//--------------------------------------------------------------------------------------

    /**
     * @function: fn_sol2lun($pYear,$pMonth,$pDay)
     * @return  : string(yyyy-mm-dd-간지-띠)
     * @brief:    양력을 음력으로 변환하는 함수
     **/
function fn_sol2lun($pYear,$pMonth,$pDay) {
$getYEAR = $pYear;
$getMONTH = $pMonth;
$getDAY = $pDay;
//$getYEAR = (int)substr($yyyymmdd,0,4);
//$getMONTH = (int)substr($yyyymmdd,4,2);
//$getDAY = (int)substr($yyyymmdd,6,2);

$arrayDATASTR = fn_sunlunar_data();
$arrayDATA = explode("-",$arrayDATASTR);

$arrayLDAYSTR="31-0-31-30-31-30-31-31-30-31-30-31";
$arrayLDAY = explode("-",$arrayLDAYSTR);

$arrayYUKSTR="갑-을-병-정-무-기-경-신-임-계";
$arrayYUK = explode("-",$arrayYUKSTR);

$arrayGAPSTR="자-축-인-묘-진-사-오-미-신-유-술-해";
$arrayGAP = explode("-",$arrayGAPSTR);

$arrayDDISTR="쥐-소-호랑이-토끼-용-뱀-말-양-원숭이-닭-개-돼지";
$arrayDDI = explode("-",$arrayDDISTR);

$arrayWEEKSTR="일-월-화-수-목-금-토";
$arrayWEEK = explode("-",$arrayWEEKSTR);

$dt = $arrayDATA;

for ($i=0;$i<=168;$i++) {
    $dt[$i] = 0;
    for ($j=0;$j<12;$j++) {
        switch (substr($arrayDATA[$i],$j,1)) {
        case 1:
        $dt[$i] += 29;
        break;
        case 3:
        $dt[$i] += 29;
        break;
        case 2:
        $dt[$i] += 30;
        break;
        case 4:
        $dt[$i] += 30;
        break;
        }
    }

    switch (substr($arrayDATA[$i],12,1)) {
    case 0:
    break;
    case 1:
    $dt[$i] += 29;
    break;
    case 3:
    $dt[$i] += 29;
    break;
    case 2:
    $dt[$i] += 30;
    break;
    case 4:
    $dt[$i] += 30;
    break;
    }
}


$td1 = 1880 * 365 + (int)(1880/4) - (int)(1880/100) + (int)(1880/400) + 30;
$k11 = $getYEAR - 1;

$td2 = $k11 * 365 + (int)($k11/4) - (int)($k11/100) + (int)($k11/400);

if ($getYEAR % 400 == 0 || $getYEAR % 100 != 0 && $getYEAR % 4 == 0) {
    $arrayLDAY[1] = 29;
    }
    else {
    $arrayLDAY[1] = 28;
    }

if ($getMONTH > 13) {
    $gf_sol2lun = 0;
}

if ($getDAY > $arrayLDAY[$getMONTH-1]) {
    $gf_sol2lun = 0;
}

for ($i=0;$i<=$getMONTH-2;$i++) {
    $td2 += $arrayLDAY[$i];
}

$td2 += $getDAY;
$td = $td2 - $td1 + 1;
$td0 = $dt[0];

for ($i=0;$i<=168;$i++) {
    if ($td <= $td0) {
    break;
    }
    $td0 += $dt[$i+1];
}

$ryear = $i + 1881;
$td0 -= $dt[$i];
$td -= $td0;

if (substr($arrayDATA[$i], 12, 1) == 0) {
    $jcount = 11;
    }
    else {
        $jcount = 12;
    }
$m2 = 0;

for ($j=0;$j<=$jcount;$j++) { // 달수 check, 윤달 > 2 (by harcoon)
    if (substr($arrayDATA[$i],$j,1) <= 2) {
        $m2++;
        $m1 = substr($arrayDATA[$i],$j,1) + 28;
        $gf_yun = 0;
        $yundal = null;     // add ksc
    }
    else {
        $m1 = substr($arrayDATA[$i],$j,1) + 26;
        $gf_yun = 1;
        $yundal = "윤달"; // add ksc
    }
    if ($td <= $m1) {
    break;
    }
    $td = $td - $m1;
}

$k1=($ryear+6) % 10;
$syuk = $arrayYUK[$k1];
$k2=($ryear+8) % 12;
$sgap = $arrayGAP[$k2];
$sddi = $arrayDDI[$k2];

$gf_sol2lun = 1;

return ($ryear."-".$m2."-".$td."-".$syuk.$sgap."년-".$sddi."띠-".$yundal);
}

//------------------------------------------------------------------------
    /**
     * @function: fn_sol2lun_ary($pYear, $pMonth)
     * @return  : array
     * @brief:    년간 양력 일자에 대응되는 음력일자 어레이 리턴
     **/
Function fn_sol2lun_ary($pYear, $pMonth) {
    /******************************************************
    *년간 양력 일자에 대응되는 음력일자 어레이 (예:2009-7-15-윤달)
    *******************************************************/

//  For ($i = 0; $i<13; $i++) {
//      For ($j = 0; $j <32; $j++ ) {
//          $aHoli[$i][$j] = null;
//      }
//  }
    $aHoli = null;

    for ($i=$pMonth; $i < $pMonth+1; $i++ ) {   //당월만
        for ($j=0; $j < 32; $j++ ) {
            if ($i > 0 && $j>0 && $j < 32) {      // 1-12
                $temp01 = explode("-",fn_sol2lun($pYear,$i,$j));
                $iSunYmd =$temp01[0]."-".$temp01[1]."-".$temp01[2];

                if ($temp01[5] != null) {   //윤달일 경우 - 붙여서 출력
                $Yundal = "-".$temp01[5];
                }
                else {
                    $Yundal = null;
                }

                $aHoli[$i][$j] = $iSunYmd.$Yundal;
            }
        }
    }
    return $aHoli;
}


//------------------------------------------------------------------------
    /**
     * @function: fn_ganji_ary($pYear, $pMonth, $pDay)
     * @return  : array
     * @brief:    간지가 새로 시작되는 새해 시작일을 입력받아 양력에 대응되는 세차, 일진 어레이 리턴
     * @brief:    유효기간 1902 - 2037
     **/
Function fn_ganji_ary($pYear, $pMonth, $pDay) {
    //*****************************************************
    // 년간 양력 일자에 대응되는 간지 어레이 (세차, 일진) 계산
    //
    // 새해의 시작을 구분 할때 사람에 따라 이론이 있으니 아래 내용 참고 하세요.
    //
    // "주역을 하시는 분들은 새해의 시작을 동지로 보고,
    // 명리학이나 사주를 보는 분들은 새해의 시작을 입춘으로 보는것 같습니다만,
    // 새해의 시작은 정월 초하루입니다."  - (한국천문연구원 홈페이지내 질문답변 게시판에서 발췌)
    //
    // 위와 같이 새해 시작점은 사람에 따라 기준점이 다르다고 합니다.
    //
    // 그러나, 기준일이 바뀌면 일자의 간지(일진)는 변하지 않지만 년의 간지(세차)와 월의 간지(월권)는
    // 변경이 되니 얼마나 난감한 일인지 모르겠습니다.
    // 사실 어느 기준을 적용하느냐에 따라 달라지는 자료(팔자)를 이용해 흔히들 사주를 본다거나 하는 일이
    // 조금은 황당하다는 생각도 듭니다.
    //
    // 그러나 간지는 우리 선조들이 계속 사용해 왔고 그중 일진은 과거 수천년 동안 그 주기가 변하지 않고
    // 계속 이어져 내려 왔다고 하니 나름 매우 중요한 자료라고 생각 합니다.
    //
    // 본 함수는 날짜를 고정 하지 않고 호출시 넘어온 일자를 새해 시작일로 하여 세차와 일진을 계산 합니다.
    // 넘어온 날이 8월 보다 적을 경우는 설날과, 입춘이라고 가정 햇습니다.
    //
    // 또 고려 할 다른 문제점은 입춘이나 동지를 시작일로 할경우는 입춘이나 동지 일자를 강제로 지정하지 않고
    // 계산을 할 경우(본 함수) 그 계산이 정확해야 되는데 정확한 24절기 계산이 쉬운일이 아니라고 합니다.
    // 현재 구할 수 있는 24절기 계산 함수들은 천체 운동 계산에 약간의 오차가 있는듯 하며,
    // 그 결과 24절기가 간혹 하루 정도 차이가 나는 경우가 있음을 염두에 두시고 이용 하시기 바랍니다.
    //(실제 계산상 차이가 몇 시간 이라고 해도 이것이 24:00시 기준 전날인지 다음날 인지에 따라서도 날자가 바뀜니다.)
    //
    //참고로 한국천문연구원이 게시한 24절기는 http://www.kasi.re.kr/Knowledge/almanac.aspx 에서 확인할 수 있습니다.
    //******************************************************

    if ($pYear<1902 || $pYear>2037) {       // 유효기간 1902-2037
        return;
    }

//  F|| ($i = 0; $i<13; $i++) {
//      For ($j = 0; $j <32; $j++ ) {
//          $aHoli[$i][$j] = null;
//      }
//  }
$aHoli = null;

$arr_gan = array("甲","乙","丙","丁","戊","己","庚","辛","壬","癸");
$arr_ji =  array("子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥");

$arr_ganji =  array('甲子','乙丑','丙寅','丁卯','戊辰','己巳','庚午','辛未','壬申','癸酉','甲戌','乙亥',
                '丙子','丁丑','戊寅','己卯','庚辰','辛巳','壬午','癸未','甲申','乙酉','丙戌','丁亥',
                '戊子','己丑','庚寅','辛卯','壬辰','癸巳','甲午','乙未','丙申','丁酉','戊戌','己亥',
                '庚子','辛丑','壬寅','癸卯','甲辰','乙巳','丙午','丁未','戊申','己酉','庚戌','辛亥',
                '壬子','癸丑','甲寅','乙卯','丙辰','丁巳','戊午','己未','庚申','辛酉','壬戌','癸亥');

// 월건을 위해 세차의 간지중 간만 출력을 위해
$arr_ganji_WG =  array('甲','乙','丙','丁','戊','己','庚','辛','壬','癸','甲','乙',
                '丙','丁','戊','己','庚','辛','壬','癸','甲','乙','丙','丁',
                '戊','己','庚','辛','壬','癸','甲','乙','丙','丁','戊','己',
                '庚','辛','壬','癸','甲','乙','丙','丁','戊','己','庚','辛',
                '壬','癸','甲','乙','丙','丁','戊','己','庚','辛','壬','癸');

    $baseYear = 1902;  // 1902년 1월 1일: 세차-"임인壬寅",  일진-"갑신甲申" 인데
                       // 어레이 arr_ganji 값으로 세차는 "38, 일진은 "20"에 해당

    $base_date = "1902-1-1";

// ---세차계산 (절기의 새해 시작점)---

    $k = ($pYear - $baseYear+38) % 60 ; // 60으로 나눈 나머지
                                        // 해당년의 세차를 arr_ganji 어레이에 맞게 조정 (38)

    if ($pMonth < 8 ) {             // 기준월 이 8월 보다 작은경우(설날과 입춘이 기준일경우)
        if ($k-1 < 0 ) {
            $Secha1=$arr_ganji_WG[59]."-".$arr_ganji[59];       // 기준일 이전의 세차
        }
        else {
            $Secha1=$arr_ganji_WG[$k-1]."-".$arr_ganji[$k-1];
        }

        $Secha2 =$arr_ganji_WG[$k]."-".$arr_ganji[$k];      // 기준일 부터의 세차

    }
    else {                              // 동지일 경우
        if ($k+1 > 59 ) {
            $Secha2=$arr_ganji_WG[0]."-".$arr_ganji[0];     // 기준일 부터의 세차
        }
        else {
            $Secha2=$arr_ganji_WG[$k+1]."-".$arr_ganji[$k+1];
        }

        $Secha1 = $arr_ganji_WG[$k]."-".$arr_ganji[$k];     // 기준일 이전의 세차

    }

// ---일진 추가 ---
    for ($i=1; $i < 13; $i++ ) {        // 입력받은 월 일은 새해 시작일임.
        for ($j=1; $j < 32; $j++ ) {
            if ($i > 0 && $j>0 && $j < 32) {
                $startdate = date("Y-n-j", mktime(0, 0, 0, $i, $j, $pYear));
                $pastdays = (strtotime($startdate)-strtotime($base_date))/86400;  //  1902-1-1 부터 해당년 1월 1일 직전 까지 경과일
                $k = ($pastdays+21) % 60;       // 해당일의 일진을 arr_ganji 어레이에 맞게 조정 (21)

                if ($i < $pMonth || $i == $pMonth && $j < $pDay) {
                $aHoli[$i][$j] = $Secha1."年-".$arr_ganji[$k]."日";
                }
                else {
                $aHoli[$i][$j] = $Secha2."年-".$arr_ganji[$k]."日";
                }
            }
        }
    }

    return $aHoli;

}

//------------------------------------------------------------------------
    /**
     * @function: fn_jeolki_ganji_ary($pYear,$pJeolki=array(),$pOption)
     * @return  : array
     * @brief:    년간 양력 일자에 대응되는 24절기, 간지 등을 입력한 어레이 리턴
     **/
Function fn_jeolki_ganji_ary($pYear,$pJeolki,$pOption) {
    /******************************************************
    * 년간 양력 일자에 대응되는 절기 어레이
    * class.solar.php function에서 나온 어레이를 입력받아 양력 일자에 해당하는
    * 어레이에 절기 이름을 입력.
    * 절기 일자를 얻은 함수는 $terms = solar::terms(date('Y'),1,12,&$sun)
    * $terms 어레이는 1232 개의 요소를 가짐(0월0일 부터 12월 31일)
    * 예로 4월 5일이 청명 이라면 $terms[405]에 "청명" 이 들어있음.
    *******************************************************/

//  For ($i = 0; $i<13; $i++) {
//      For ($j = 0; $j <32; $j++ ) {
//          $aHoli[$i][$j] = null;
//      }
//  }
    $aHoli = null;

//---어레이 구조조정 -------
    For ($i = 0; $i<13; $i++) {
        For ($j = 0; $j <32; $j++ ) {
            if ($j<10) {                //1-9일
                $k = "0".$j;
                $jeolki[$i][$j] = $pJeolki[$i.$k];
            }
            else {
                $jeolki[$i][$j] = $pJeolki[$i.$j];
            }
        }
    }

// 간지 시작 기준날자 설정 : 입력 받은 option에 의해.
    switch ($pOption) {
      case (1):
        $ganjioption = "설날";        // 설날을 새해 첫날로 간주.
        break;
      case (2):
        $ganjioption = "입춘";        // 명리학, 사주 위주 (입춘을 새해 첫날로 간주).
        break;
      case (3):
        $ganjioption = "동지";        // 주자학 위주 (동지를 새해 첫날로 간주).
        break;
      default:                      // option 없을때
        $ganjioption = "설날";        // 설날을 새해 첫날로 간주.
        break;
    }

// 음력 1월 1일  양력날자 구하기  (세차 계산을 위해)------------------------
    $lunfirstday = explode("-",fn_lun2sol($pYear,1,1));
    $SeolMM = $lunfirstday[1];      // 세차(년 간지)가 바뀌는 일자 월  (음력 1월 1일)
    $SeolDD = $lunfirstday[2];      // 세차(년 간지)가 바뀌는 일자 일  (음력 1월 1일)


//---option에따른 월권을 위한 임시 절기 어레이 생성  설날은 음력 월로 구분하니 필요 없음-----
    For ($i = 1; $i<13; $i++) {
        For ($j = 1; $j <32; $j++ ) {


//설날기점:    매월 음력 1일에 구분으로 절기와 무관
            if ($ganjioption == "설날" ) {
                for ($i=1; $i < 13; $i++ ) {
                    for ($j=1; $j < 32; $j++ ) {
                        $wrklunday = explode("-",fn_sol2lun($pYear,$i,$j)); // 음력 날자 구하기
                        if ($wrklunday[2] == 1 && $wrklunday[5] == null) { // 월첫날이며 윤달이 아닐때
                            $WGjeolki[$i][$j] = $wrklunday[0]."-".$wrklunday[1]."-".$wrklunday[2];
                        }
                    }
                }
            }

        }
    }

//---24 절기 주석처리 및 주요날자 얻기-----------------------
    for ($i=1; $i < 13; $i++ ) {
        for ($j=1; $j < 32; $j++ ) {
            $aHoli[$i][$j] = $jeolki[$i][$j];

            // 콤멘트 추가
            switch ($aHoli[$i][$j]) {
               case ("소한"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("대한"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("입춘"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                $IpchunMM = $i;     // 입춘 일자 월 (입춘)
                $IpchunDD = $j;     // 입춘 일자 일  (입춘)
                break;
               case ("우수"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("경칩"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("춘분"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                $ChunbunMM = $i;    // 춘분 일자 월
                $ChunbunDD = $j;    // 춘분 일자 일
                break;
               case ("청명"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("곡우"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("입하"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("소만"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("망종"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("하지"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                $HajiMM = $i;       // 하지 일자 월
                $HajiDD = $j;       // 하지 일자 일
                break;
               case ("소서"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("대서"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("입추"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                $IpchuMM = $i;      // 입추 일자 월
                $IpchuDD = $j;      // 입추 일자 일
                break;
               case ("처서"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("백로"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("추분"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                $ChubunMM = $i;     // 추분 일자 월
                $ChubunDD = $j;     // 추분 일자 일
                break;
               case ("한로"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("상강"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("입동"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("소설"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("대설"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                break;
               case ("동지"):
                $aHoli[$i][$j] = $aHoli[$i][$j]."";
                $DongjiMM = $i;     // 동지 일자 월
                $DongjiDD = $j;     // 동지 일자 일

            }
        }
    }
// ---- 간지 시작일 을 조건에 따라 설정 ----
    if ($ganjioption == "설날"):
        $GanjiStartMM = $SeolMM;
        $GanjiStartDD = $SeolDD;
    elseif ($ganjioption == "입춘"):
        $GanjiStartMM = $IpchunMM;
        $GanjiStartDD = $IpchunDD;
    elseif ($ganjioption == "동지"):
        $GanjiStartMM = $DongjiMM;
        $GanjiStartDD = $DongjiDD;
    else:
        $GanjiStartMM = $SeolMM;        // 설날로 설정
        $GanjiStartDD = $SeolDD;
    endif;

// --세차와 일진을 구한다------------------------------
    $arr_Secha = fn_ganji_ary($pYear, $GanjiStartMM, $GanjiStartDD);


// --- 초복, 중복, 말복 계산(하지, 추분 및 일진을 조합하여 계산-------------
// 초복, 중복: 하지 로부터 세 번째(초복), 네번째(중복) 돌아오는 경일
// 말복      : 입추로부터 첫 번째 경일
// 하지 일자 월, 일: $HajiMM  $HajiDD
// 입추 일자 월, 일: $IpchuMM $IpchuDD
// 경일:'庚午','庚辰','庚寅','庚子','庚戌','庚申'  // 문자열 자르기가 안되서 비교로 처리함

//-- 초복, 중복 --------
    $k = 0;
    For ($i = $HajiMM; $i<13; $i++) {
        For ($j = 1; $j <32; $j++ ) {
            if ($i > $HajiMM || $i == $HajiMM && $j >= $HajiDD ) {

            $temp01 = explode("-",$arr_Secha[$i][$j]);
            $wrkfld01 = $temp01[2];
            if($wrkfld01 == "庚午日" || $wrkfld01 == "庚辰日" || $wrkfld01 == "庚寅日" || $wrkfld01 == "庚子日" ||  $wrkfld01 == "庚戌日" || $wrkfld01 == "庚申日") {
                $k = $k + 1;
                if ($k == 3) {
                    $aHoli[$i][$j] = $aHoli[$i][$j]."초복";
                }
                if ($k == 4) {
                    $aHoli[$i][$j] = $aHoli[$i][$j]."중복";
                    break;
                }
            }

            }
        }
    }

// -- 말복 ---
    $k = 0;
    For ($i = $IpchuMM; $i<13; $i++) {
        For ($j = 1; $j <32; $j++ ) {
            if ($i > $IpchuMM || $i == $IpchuMM && $j >= $IpchuDD ) {

            $temp01 = explode("-",$arr_Secha[$i][$j]);
            $wrkfld01 = $temp01[2];
            if($wrkfld01 == "庚午日" || $wrkfld01 == "庚辰日" || $wrkfld01 == "庚寅日" || $wrkfld01 == "庚子日" ||  $wrkfld01 == "庚戌日" || $wrkfld01 == "庚申日") {
                $k = $k + 1;
                if ($k == 1) {
                    $aHoli[$i][$j] = $aHoli[$i][$j]."말복";
                    break;
                }
            }

            }
        }
    }

// 기타 음력절기 상 특별한날 ------------------------
    $aMoon[5][5]  = "단오";
    $aMoon[7][7]  = "칠석";
    $aMoon[7][15] = "백중";

    for ($i=1; $i < 13; $i++ ) {
        for ($j=1; $j < 32; $j++ ) {
            if ($aMoon[$i][$j] != null) {       // 자료가 있으면 양력으로 환산하여 자료 추가
                $temp01 = explode("-",fn_lun2sol($pYear,$i,$j));
                $iLunYmd =date("Y-n-j", mktime(0, 0, 0,$temp01[1], $temp01[2], $temp01[0]));
                $temp02 = explode("-",$iLunYmd);
                $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]].$aMoon[$i][$j];
            }
        }
    }

//---- 한식일자 구하기: 한식은 전년도 동지에서 105일째 되는 날인바
// 전년도 동지일을 기준으로 계산 하여야 하나 편의를 위해 테이블로 작업함
// 아래 테이블은 2000년부터 2050년까지 4월 6일인 경우의 해이고
// 테이블에 없는 해는 4월 5일이 한식임.

    $arr_HansikYear =  array('2002','2003','2006','2007','2010','2011','2014','2015','2018','2019','2022','2023','2027','2031','2035','2039','2043','2047');

    if ($pYear >=2000 && $pYear <=2050) {
        for ($i=0; $i<50; $i++ ) {
            if ($arr_HansikYear[$i] == $pYear) {
                $wrk_hansik = $i;
                break;
            }
        }
        if ($wrk_hansik != null ) {
            $aHoli[4][6] = $aHoli[4][6]."한식";
        }
        else {
            $aHoli[4][5] = $aHoli[4][5]."한식";
        }
    }

//---- 절기와 간지 합하여 어레이 리턴---
    For ($i = 1; $i<13; $i++) {
        For ($j = 1; $j <32; $j++ ) {
            $aHoli[$i][$j] = $arr_Secha[$i][$j]."-".$arr_WolGeon[$i][$j]."-".$aHoli[$i][$j];
        }
    }
    return $aHoli;

}

//-----------------------------------------------------------------------------------
     /**
     * @function: fn_easterday($pYear)
     * @return  : string
     * @brief:    해당년 부활절 일자를 구한다
     **/
function fn_easterday($pYear) {
    $k=easter_days($pYear);
    if ($k>10) {
        $wrkYmd =date("Y-n-j", mktime(0, 0, 0,4, $k-10, $pYear));
    }
    else   {
        $wrkYmd =date("Y-n-j", mktime(0, 0, 0,3, $k+21, $pYear));
    }
    return $wrkYmd;
}

//-----------------------------------------------------------------------------------
	 /**
     * @function: fn_easterday_2($pYear)
     * @return  : string
     * @brief:    해당년 부활절 일자를 구한다 (가우스공식이용) - 간혹 PHP에서 부활절함수 지원 안될때 이용
     **/
function fn_easterday_2($pYear) {
 $M = 24; // 1900-2099 년도분만 사용
 $N = 5;  // 1900-2099 년도분만 사용
    $A = $pYear % 19;
    $B = $pYear % 4;
    $C = $pYear % 7;
    $D = (19 * $A + $M) % 30;
    $E = ((2 * $B) + (4 * $C) + (6 * $D) + $N) % 7;
    $Tag1 = (22 + $D + $E);
    $Tag2 = ($D + $E - 9);

 if($Tag1 <= 31 ) {
   $easterday = mktime(0, 0, 0, 3, $Tag1, $pYear); // 3월 부활절 일자 타임스탬프
   $wrkYmd =date("Y-n-j", $easterday);
  }
  else {
   $easterday = mktime(0, 0, 0, 4, $Tag2, $pYear); // 4월 부활절 일자 타임스탬프
   $wrkYmd =date("Y-n-j", $easterday);
  }

    return $wrkYmd;
}

//--------------------------------------------------------------------------------------
    /**
     * @function: fn_HolidayChk($pYear, $pMonth)
     * @return  : array
     * @brief:    휴일 여부
     **/
Function fn_HolidayChk($pYear, $pMonth) {
    /******************************************************
    *휴일은 음력에서 1.1(설)/8.15(추석)/4.8(석가탄신일) 이 있으며
    *양력으로 1.1(신정)/3.1(삼일절)/5.5(어린이날)/6.6(현충일)/8.15(광복절)/10.3(개천절)/12.25(성탄절) 이다.
      (4.5: 2006년부터 식목일은 법정 공휴일에서 법정기념일 기년일로바뀜)
      (7.17: 2008년 부터 제헌절은 법정 공휴일에서 법정기념일 기년일로바뀜)
    *설과 추석은 앞뒤로 하루씩 휴일이 더해진다.
    *******************************************************/

//  For ($i = 0; $i<13; $i++) {
//      For ($j = 0; $j <32; $j++ ) {
//          $aHoli[$i][$j] = null;
//      }
//  }
    $aHoli = null;

    //양력 휴일(국경일,기념일중 휴일)
    $aHoli[1][1] = "신정 ";
    $aHoli[3][1] = "삼일절 ";
    $aHoli[5][5] = "어린이날 ";
    $aHoli[6][6] = "현충일 ";
//  $aHoli[7][17] = "제헌절 "; // 국경일이나 휴일아님
    $aHoli[8][15] = "광복절 ";
    $aHoli[10][3] = "개천절 ";
//  $aHoli[10][9] = "한글날 "; // 국경일이나 휴일아님
    $aHoli[12][25] = "성탄절 ";

    //음력휴일
    //(설날)
    $temp01 = explode("-",fn_lun2sol($pYear,1,1));
    $iLunYmd =date("Y-n-j", mktime(0, 0, 0,$temp01[1], $temp01[2], $temp01[0]));
    $iLunYmdpre =date("Y-n-j", mktime(0, 0, 0,$temp01[1], $temp01[2]-1, $temp01[0]));
    $iLunYmdnext =date("Y-n-j", mktime(0, 0, 0,$temp01[1], $temp01[2]+1, $temp01[0]));

    $temp02 = explode("-",$iLunYmd);
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]."설날";
    $temp02 = explode("-",$iLunYmdpre);
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]."설연휴";
    $temp02 = explode("-",$iLunYmdnext);
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]."설연휴";


    //(추석)
    $temp01 = explode("-",fn_lun2sol($pYear,8,15));
    $iLunYmd =date("Y-n-j", mktime(0, 0, 0,$temp01[1], $temp01[2], $temp01[0]));
    $iLunYmdpre =date("Y-n-j", mktime(0, 0, 0,$temp01[1], $temp01[2]-1, $temp01[0]));
    $iLunYmdnext =date("Y-n-j", mktime(0, 0, 0,$temp01[1], $temp01[2]+1, $temp01[0]));

    $temp02 = explode("-",$iLunYmd);
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]."추석";
    $temp02 = explode("-",$iLunYmdpre);
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]."추석연휴";
    $temp02 = explode("-",$iLunYmdnext);
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]."추석연휴";


    //(석가탄신일)
    $temp01 = explode("-",fn_lun2sol($pYear,4,8));
    $iLunYmd =date("Y-n-j", mktime(0, 0, 0,$temp01[1], $temp01[2], $temp01[0]));
    $temp02 = explode("-",$iLunYmd);
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]."석가탄신일";

    return $aHoli;
}

//------------------------------------------------------------------------
    /**
     * @function: fn_MemdayChk($pYear, $pMonth)
     * @return  : boolean
     * @brief:    기념일 여부
     **/
Function fn_MemdayChk($pYear, $pMonth) {
    /******************************************************
    *법정 기념일과 공휴일이 아닌 국경일
    *음력 기념일 등
    *******************************************************/
    $aHoli = null;

//음력 기념일  $aMoon[월][일][평달=0, 윤달=1, 윤달및평달=2] 형식으로....
//음력은 일년에 같은 월 같은 날이 두번 들어 있을 수 있음.
//  $aMoon[11][9][0] = $aMoon[11][9][0]."<B>조부기일</B><BR>";  // 음력11월 9일 (평달)
//  $aMoon[8][26][0] = $aMoon[8][26][0]."조카생일<BR>";         // 음력8월 26일 (평달)
//  $aMoon[5][16][1] = $aMoon[5][16][1]." <B>**윤달테스트**</B>";    // 음력윤달 (윤달만 적용)
//  $aMoon[4][18][2] = $aMoon[4][18][2]." <B>**윤달및평달테스트**</B>";    // 윤달및 평달: (윤달, 윤달 없으면 평달)
//  $aMoon[11][24][0] = $aMoon[11][24][0]." <B>**중복테스트**</B>";  // 1년에 두번 예:2008년

    $iLunYmd_arr = fn_sol2lun_ary($pYear, $pMonth); // 당월 양력에 해당되는 음력일자 어레이 얻기

    for ($i=1; $i < 13; $i++ ) {
        for ($j=1; $j < 32; $j++ ) {
            if ($aMoon[$i][$j][0] != null || $aMoon[$i][$j][1] != null || $aMoon[$i][$j][2] != null) {  // 기념일이 있으면..
                $lunmemMM = $i;
                $lunmemDD = $j;

                for ($k=$pMonth; $k < $pMonth+1; $k++ ) {
                    for ($d=1; $d < 32; $d++ ) {
                        $iLunYmd = explode("-",$iLunYmd_arr[$k][$d]);   // 음력 어레이를 읽어서
                        $iLunMM = $iLunYmd[1];
                        $iLunDD = $iLunYmd[2];
                        $Yundal = $iLunYmd[3];

                        if ($aMoon[$lunmemMM][$lunmemDD][0] != null ) {     // 음력(평달) 기념일에 해당되는 양력 날자에..
                            if ($iLunMM == $lunmemMM  && $iLunDD == $lunmemDD && $Yundal == null ) {
                                $aHoli[$k][$d] = $aHoli[$k][$d].$aMoon[$i][$j][0];
                            }
                        }
                        if ($aMoon[$lunmemMM][$lunmemDD][1] != null ) {     // 음력(윤달) 기념일에 해당되는 양력 날자에..
                            if ($iLunMM == $lunmemMM  && $iLunDD == $lunmemDD && $Yundal != null ) {
                                $aHoli[$k][$d] = $aHoli[$k][$d].$aMoon[$i][$j][1];
                            }
                        }
                        if ($aMoon[$lunmemMM][$lunmemDD][2] != null ) {     // 음력(윤달)및 평달: 윤달 있으면 윤달, 없으면 평달 기념일에 해당되는 양력 날자에..
						$tmp_arr = explode("-",fn_lun2sol($pYear,$lunmemMM,$lunmemDD));  // 당월에 윤달있는지...[4]==1
						  if ($tmp_arr[4] == 1) {
							if ($iLunMM == $lunmemMM  && $iLunDD == $lunmemDD && $Yundal != null ) {
                                $aHoli[$k][$d] = $aHoli[$k][$d].$aMoon[$i][$j][2];
							}
						  } else {
							if ($iLunMM == $lunmemMM  && $iLunDD == $lunmemDD && $Yundal == null ) {
                                $aHoli[$k][$d] = $aHoli[$k][$d].$aMoon[$i][$j][2];
							}
						  }
                        }

					}   // end for
                }       // end for

            }           // end if
        }               // end for
    }                   // end for


//양력기념일 (기념일,국경일,법정기념일 - 휴일아닌경우)
//  $aHoli[5][29] = $aHoli[5][29]." 큰딸생일";
//  $aHoli[6][9] = $aHoli[6][9]." 작은딸생일";

    $aHoli[3][3] = $aHoli[3][3]." 납세자의날";
    //$aHoli[3][xx] = " 상공의날";          //3월셋째 수요일
    //$aHoli[4][xx] = " 향토예비군의날";   //4월첫째 금요일
    $aHoli[4][5] = $aHoli[4][5]." 식목일";
    $aHoli[4][7] = $aHoli[4][7]." 보건의날";
    $aHoli[4][13] = $aHoli[4][13]." 임시정부수립";
    $aHoli[4][19] = $aHoli[4][19]." 4.19기념일";
    $aHoli[4][20] = $aHoli[4][20]." 장애인의날";
    $aHoli[4][21] = $aHoli[4][21]." 과학의날";
    $aHoli[4][22] = $aHoli[4][22]." 정보통신의날";
    $aHoli[4][25] = $aHoli[4][25]." 법의날";
    $aHoli[4][28] = $aHoli[4][28]." 충무공탄신일";
    $aHoli[5][1] = $aHoli[5][1]." 근로자의날";
//  $aHoli[5][5] = $aHoli[5][5]." 어린이날";
    $aHoli[5][8] = $aHoli[5][8]." 어버이날";
    $aHoli[5][11] = $aHoli[5][11]." 입양의날";  //개별법
    $aHoli[5][15] = $aHoli[5][15]." 스승의날";
    $aHoli[5][15] = $aHoli[5][15]." 가정의날";  //개별법
    $aHoli[5][18] = $aHoli[5][18]." 5.18기념일";
    $aHoli[5][19] = $aHoli[5][19]." 발명의날";  //개별법
    $aHoli[5][20] = $aHoli[5][20]." 세계인의날"; //개별법
    $aHoli[5][21] = $aHoli[5][21]." 부부의날";
    $aHoli[5][25] = $aHoli[5][25]." 방재의날";  //개별법
    //$aHoli[5][xx] = " 성년의날";      //5월셋째 월요일
    $aHoli[5][31] = $aHoli[5][31]." 바다의날";
    $aHoli[6][5] = $aHoli[6][5]." 환경의날";
//  $aHoli[6][6] = $aHoli[6][6]." 현충일";
    $aHoli[6][10] = $aHoli[6][10]." 6.10기념일";
    $aHoli[6][25] = $aHoli[6][25]." 6.25사변일";
    $aHoli[7][17] = $aHoli[7][17]." 제헌절";       //국경일
    $aHoli[9][1] = $aHoli[9][1]." 통계의날";    //개별법
    $aHoli[9][4] = $aHoli[9][4]." 태권도의날";   //개별법
    $aHoli[9][7] = $aHoli[9][7]." 사회복지의날";  //개별법
    $aHoli[9][18] = $aHoli[9][18]." 철도의날";
    $aHoli[10][1] = $aHoli[10][1]." 국군의날";
    $aHoli[10][2] = $aHoli[10][2]." 노인의날";
    $aHoli[10][5] = $aHoli[10][5]." 세계한인의날";
    $aHoli[10][8] = $aHoli[10][8]." 재향군인의날";
    $aHoli[10][9] = $aHoli[10][9]." 한글날";       //국경일
    $aHoli[10][10] = $aHoli[10][10]." 임산부의날";   //개별법
    $aHoli[10][15] = $aHoli[10][15]." 체육의날";
    //$aHoli[10][xx] = " 문화의날";     //10월셋째 토요일
    $aHoli[10][21] = $aHoli[10][21]." 경찰의날";
    $aHoli[10][24] = $aHoli[10][24]." 국제연합일";
    $aHoli[10][28] = $aHoli[10][28]." 교정의날";
    //$aHoli[10][xx] = " 저축의날";     //10월마지막화요일
    $aHoli[11][3] = $aHoli[11][3]." 학생독립운동기념일";
    $aHoli[11][9] = $aHoli[11][9]." 소방의날";  //개별법
    $aHoli[11][11] = $aHoli[11][11]." 농업인의날";
    $aHoli[11][17] = $aHoli[11][17]." 순국선열의날";
    $aHoli[11][30] = $aHoli[11][30]." 무역의날";
    $aHoli[12][3] = $aHoli[12][3]." 소비자의날";
    $aHoli[12][5] = $aHoli[12][5]." 자원봉사자의날";   //개별법

    // 몇월 몇번째 무슨요일 형식 기념일 설정 (예: 상공의날- 3월 셋째 수요일은 ($pYear, 월=3, 일=3, 수=3) 형식으로)
    $temp02 = explode("-",fn_nsweekday($pYear, 3, 3, 3));
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]." 상공의날";
    $temp02 = explode("-",fn_nsweekday($pYear, 4, 1, 5));
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]." 향군의날";
    $temp02 = explode("-",fn_nsweekday($pYear, 5, 3, 1));
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]." 성년의날";
    $temp02 = explode("-",fn_nsweekday($pYear, 10, 3, 6));
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]." 문화의날";


    // 몇월, 끝에서 몇번째 주, 무슨요일 형식 기념일 설정 (예: 저축의날- 10월마지막화요일)
    //상공의날
    $temp02 = explode("-",fn_nslastweekday($pYear, 10, 1, 2));
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]." 저축의날";

/***
    // 몇월, 몇번째 주, 무슨요일 형식 기념일 설정 (예: 10월 4번째주 금요일) -현재 해당 기념일 없음.
    //테스트용 (예: 10월 4쨰주 금요일)
    $temp02 = explode("-",fn_nsweeknsweekday($pYear, 10, 4, 5));
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]." 현재없음-테스트";
***/
/***
    // 매월, 몇번째 주, 무슨요일 형식 기념일 설정 (예: 4번째주 금요일) -현재 해당 기념일 없음.
    for ($k=1; $k < 13; $k++ ) {
    $temp02 = explode("-",fn_nsweeknsweekday($pYear, $k, 4, 5));
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]." <font color=brown>월말결산</font>";
    }
***/
/***
    // 매월, 몇번째 무슨요일 형식 기념일 설정 (예-옵션만기일: 매월 2번째 목요일)
    for ($k=1; $k < 13; $k++ ) {
    $temp02 = explode("-",fn_nsweekday($pYear, $k, 2, 4));
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]." <font color=brown>옵션만기일</font>";
    }
***/
/***
    // 몇월, 끝에서 몇번째 무슨요일 형식 기념일 설정  (예: Victoria Day=끝에서 2번째 월요일)
    $temp02 = explode("-",fn_nslastweekday($pYear, 5, 2, 1));
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]." Victoria Day";
***/
/*** 
    //(부활절)
    $temp01 = explode("-",fn_easterday($pYear));
    $iYmd =date("Y-n-j", mktime(0, 0, 0,$temp01[1], $temp01[2], $temp01[0]));
    $iYmdpre =date("Y-n-j", mktime(0, 0, 0,$temp01[1], $temp01[2]-2, $temp01[0]));
    $iYmdnext =date("Y-n-j", mktime(0, 0, 0,$temp01[1], $temp01[2]+1, $temp01[0]));

//  $temp02 = explode("-",$iYmdpre);
//  $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]."Good Friday";
    $temp02 = explode("-",$iYmd);
    $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]."부활절";
//  $temp02 = explode("-",$iYmdnext);
//  $aHoli[$temp02[1]][$temp02[2]] = $aHoli[$temp02[1]][$temp02[2]]."Easter Monday";
***/
    return $aHoli;
}

//------------------------------------------------------------------------
    /**
     * @function: fn_repeat_schedule($pYear, $pMonth, $plan_start, $plan_end, $plan_repeat_cycle, $plan_repeat_unit)
     * @return  : array
     * @brief:    반복일정이 적용되는 양력일자 어레이 리턴
     **/
Function fn_repeat_schedule($pYear, $pMonth, $plan_start, $plan_end, $plan_repeat_cycle, $plan_repeat_unit) {
    /******************************************************
    * 반복일정이 적용되는 일자에 "*" 삽입
    * 반복일정은 일정시작일을 기준으로 반복되며, 모든 반복일정은 일정 자체의 기간은 1일 간으로한다.
    * 그렇지 않을경우 일정자체의 기간을 지정할 2개의 추가 확장변수가 필요하게 되어 실익이 없다.
    *******************************************************/

    $aHoli = null;

    if ($plan_start == null ) {
        return $aHoli;
    }

    $startYY = substr($plan_start,0,4);
    $startMM = ltrim(substr($plan_start,4,2), "0" );    //  앞의 "0" 제거
    $startDD = ltrim(substr($plan_start,6,2), "0" );    //  앞의 "0" 제거
    $plnstartYY = $startYY;
    $plnstartMM = $startMM;
    $plnstartDD = $startDD;

    $endYY = substr($plan_end,0,4);
    $endMM = ltrim(substr($plan_end,4,2), "0" );    // 일자 앞의 "0" 제거
    $endDD = ltrim(substr($plan_end,6,2), "0" );    // 일자 앞의 "0" 제거
    $plnendYY = $endYY;
    $plnendMM = $endMM;
    $plnendDD = $endDD;

    $plan_startdate = mktime(0, 0, 0, $startMM, $startDD, $startYY);    // 일정시작 일자 타임스탬프
    $plan_enddate = mktime(0, 0, 0, $endMM, $endDD, $endYY);            // 일정종료 일자 타임스탬프

    $k = 12;        // 1년간 반복일정 처리 (월 반복일정)

    if ($plnstartYY == $pYear && $plnstartMM == $pMonth) {             // 당월 시작 이면서 당월 이후 종료
        if ($plnendYY > $pYear || $plnendYY == $pYear && $plnendMM > $pMonth) {
                    $plnendYY = $pYear;
                    $plnendMM = $pMonth;
                    $plnendDD = 31;
        }
    }
    elseif ($plnstartYY < $pYear || $plnstartYY == $pYear && $plnstartMM < $pMonth) {  // 당월 이전 시작 이면서 당월 종료
        if ($plnendYY == $pYear && $plnendMM == $pMonth) {
                    $plnstartYY = $pYear;
                    $plnstartMM = $pMonth;
                    $plnstartDD = 1;
        }
        if ($plnendYY > $pYear || $plnendYY == $pYear && $plnendMM > $pMonth) { // 당월 이전시작 이면서 당월 이후 종료
                    $plnstartYY = $pYear;
                    $plnstartMM = $pMonth;
                    $plnstartDD = 1;
                    $plnendYY = $pYear;
                    $plnendMM = $pMonth;
                    $plnendDD = 31;
        }
    }

    // plan_repeat_cycle 또는 plan_repeat_unit 값이 null 일때********************
    if ($plan_repeat_unit == null || $plan_repeat_cycle == null ) {
        if ( $plnstartYY == $pYear && $plnstartMM == $pMonth) {
            For ($i = $plnstartMM; $i <= $plnendMM; $i++) {
                For ($j = $plnstartDD; $j <= $plnendDD; $j++ ) {
                    $aHoli[$i][$j] =  "*";
                }
            }
        }
    }

    // unit 값이 1.일(간격) : 몇일 간결으로 반복***********************************
    elseif (substr($plan_repeat_unit,0,1) == "1" && $plan_repeat_cycle != null ) {
        $k = 365/$plan_repeat_cycle;        // 1년간 반복일정 처리
        For ($i = 0; $i <= $k; $i++ ) {
            $wrkday= $startDD + ($plan_repeat_cycle * $i);
            $wrkYY = date("Y", mktime(0, 0, 0, $startMM, $wrkday, $startYY));   // 반복될 일자-년
            $wrkMM = date("n", mktime(0, 0, 0, $startMM, $wrkday, $startYY));   // 반복될 일자-월
            $wrkDD = date("j", mktime(0, 0, 0, $startMM, $wrkday, $startYY));   // 반복될 일자-일
            $work_date = mktime(0, 0, 0, $wrkMM, $wrkDD, $wrkYY);               // 반복 일자 타임스탬프
            if( $work_date >= $plan_startdate && $work_date <= $plan_enddate && $pYear == $wrkYY) {
                $aHoli[$wrkMM][$wrkDD] =  "*";
            }
        }
    }
    // 2.개월(같은날자): 반복월 같은 날자**********************************************
    elseif (substr($plan_repeat_unit,0,1) == "2" && $plan_repeat_cycle != null ) {
        For ($i = 0; $i <= $k; $i++ ) {
            $wrkmonth= $startMM + ($plan_repeat_cycle * $i);
            $wrkYY = date("Y", mktime(0, 0, 0, $wrkmonth, $startDD, $startYY)); // 반복될 일자-년
            $wrkMM = date("n", mktime(0, 0, 0, $wrkmonth, $startDD, $startYY)); // 반복될 일자-월
            $wrkDD = date("j", mktime(0, 0, 0, $wrkmonth, $startDD, $startYY)); // 반복될 일자-일
            $work_date = mktime(0, 0, 0, $wrkMM, $wrkDD, $wrkYY);               // 반복 일자 타임스탬프
            if( $work_date >= $plan_startdate && $work_date <= $plan_enddate && $pYear == $wrkYY) {
                $aHoli[$wrkMM][$wrkDD] =  "*";
            }
        }
    }
    // 3.개월(요일차): 반복월 앞에서부터 같은번째 요일*******************************************
    elseif (substr($plan_repeat_unit,0,1) == "3" && $plan_repeat_cycle != null ) {
        $pYoil = date("w", mktime(0, 0, 0,$startMM, $startDD, $startYY));   //해당일의 요일번호(일=0, 토=6)
        $yoilcount = fn_weekdaycountofmonth($startYY,$startMM,$startDD);        // n번째 요일 숫자
        For ($i = 0; $i <= $k; $i++ ) {
            $wrkmonth= $startMM + ($plan_repeat_cycle * $i);
            $wrkYY = date("Y", mktime(0, 0, 0, $wrkmonth, $startDD, $startYY)); // 반복될 일자-년
            $wrkMM = date("n", mktime(0, 0, 0, $wrkmonth, $startDD, $startYY)); // 반복될 일자-월
            $wrkDD = date("j", mktime(0, 0, 0, $wrkmonth, $startDD, $startYY)); // 반복될 일자-일
            $temp01 = explode("-",fn_nsweekday($wrkYY, $wrkMM, $yoilcount, $pYoil));    // 해당n번째요일에 대응되는 일자 얻기
            $work_date = mktime(0, 0, 0, $temp01[1], $temp01[2], $temp01[0]);           // 반복 일자 타임스탬프
            if( $work_date >= $plan_startdate && $work_date <= $plan_enddate && $pYear == $wrkYY) {
                $aHoli[$temp01[1]][$temp01[2]] =  "*";
            }
        }
    }
    // 4.개월(주차/요일차): 반복월 앞에서부터 같은번째 주 같은요일**************************************
    elseif (substr($plan_repeat_unit,0,1) == "4" && $plan_repeat_cycle != null ) {
        $pYoil = date("w", mktime(0, 0, 0,$startMM, $startDD, $startYY));   //해당일의 요일번호(일=0, 토=6)
        $weekcount = fn_weekcountofmonth($startYY,$startMM,$startDD);           //n번째 주 숫자
        For ($i = 0; $i <= $k; $i++ ) {
            $wrkmonth= $startMM + ($plan_repeat_cycle * $i);
            $wrkYY = date("Y", mktime(0, 0, 0, $wrkmonth, $startDD, $startYY)); // 반복될 일자-년
            $wrkMM = date("n", mktime(0, 0, 0, $wrkmonth, $startDD, $startYY)); // 반복될 일자-월
            $wrkDD = date("j", mktime(0, 0, 0, $wrkmonth, $startDD, $startYY)); // 반복될 일자-일
            $temp01 = explode("-",fn_nsweeknsweekday($wrkYY, $wrkMM, $weekcount, $pYoil));  // 해당주/요일에 대응되는 일자 얻기
            $work_date = mktime(0, 0, 0, $temp01[1], $temp01[2], $temp01[0]);               // 반복 일자 타임스탬프
            if( $work_date >= $plan_startdate && $work_date <= $plan_enddate && $pYear == $wrkYY) {
                $aHoli[$temp01[1]][$temp01[2]] =  "*";
            }
        }
    }
    // 5.개월(말일): 반복월 말일****************************************************
    elseif (substr($plan_repeat_unit,0,1) == "5" && $plan_repeat_cycle != null ) {
        For ($i = 0; $i <= $k; $i++ ) {
            $wrkmonth= $startMM + ($plan_repeat_cycle * $i);
            $wrkYY = date("Y", mktime(0, 0, 0, $wrkmonth, $startDD, $startYY)); // 반복될 일자-년
            $wrkMM = date("n", mktime(0, 0, 0, $wrkmonth, $startDD, $startYY)); // 반복될 일자-월
            $wrkDD = date("j", mktime(0, 0, 0, $wrkmonth, $startDD, $startYY)); // 반복될 일자-일
            $wrklastday= date("t", mktime(0, 0, 0, $wrkmonth, 1, $startYY));    // 반복될 마지막 날자
            $work_date = mktime(0, 0, 0, $wrkMM, $wrklastday, $wrkYY);          // 반복 일자 타임스탬프
            if( $work_date >= $plan_startdate && $work_date <= $plan_enddate && $pYear == $wrkYY) {
                $aHoli[$wrkMM][$wrklastday] =  "*";
            }
        }
    }
    // 6.개월(월말부터요일차): 반복월 끝에서부터 같은번째 요일****************************************************
    elseif (substr($plan_repeat_unit,0,1) == "6" && $plan_repeat_cycle != null ) {
        $pYoil = date("w", mktime(0, 0, 0,$startMM, $startDD, $startYY));    //해당일의 요일번호(일=0, 토=6)
        $yoilcount = fn_weekdaycountofmonth_end($startYY,$startMM,$startDD); //해당일의 말일에서부터의 n번째 요일 숫자
        For ($i = 0; $i <= $k; $i++ ) {
            $wrkmonth= $startMM + ($plan_repeat_cycle * $i);
            $wrkYY = date("Y", mktime(0, 0, 0, $wrkmonth, $startDD, $startYY)); // 반복될 일자-년
            $wrkMM = date("n", mktime(0, 0, 0, $wrkmonth, $startDD, $startYY)); // 반복될 일자-월
            $wrkDD = date("j", mktime(0, 0, 0, $wrkmonth, $startDD, $startYY)); // 반복될 일자-일
            $temp01 = explode("-",fn_nslastweekday($wrkYY, $wrkMM, $yoilcount, $pYoil)); // 끝에서 n번째요일에 대응되는 일자 얻기
            $work_date = mktime(0, 0, 0, $temp01[1], $temp01[2], $temp01[0]);           // 반복 일자 타임스탬프
            if( $work_date >= $plan_startdate && $work_date <= $plan_enddate && $pYear == $wrkYY) {
                $aHoli[$temp01[1]][$temp01[2]] =  "*";
            }
        }
    }

    return $aHoli;
}

//------------------------------------------------------------------------
    /**
     * @brief XE에 설정된 타임존을 반영한 시간값을 구함
     * @param none,  XE함수 zgap() 사용
     * @return int
     **/
function fn_xetimestamp() {
    $localtimestamp = mktime(date("H"), date("i"), date("s")+zgap(), date("m"), date("d"), date("Y"));
    return $localtimestamp;
}


?>

<!--// -----function 끝 --------------- -->

