본문 바로가기
Web-Front/JavaScript

[JavaScript] 양력을 음력으로 변환, 음력을 양력으로 변환

by usang0810 2020. 5. 28.

양력달력의 경우 Javascript의 Date객체를 사용하면 쉽게 만들 수 있지만 음력달력을 만들려고 보니 생각보다 어려웠다.

먼저 음력이 어떻게 만들어지는지도 몰랐고 음력의 규칙성을 찾을 수 없었다. 구글링하며 소스를 찾다가 좋은 소스를 찾아서 조금 수정하고 주석을 추가로 달아서 적용했다.

 

https://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040202&docId=69098309&qb=amF2YXNjcmlwdCDslpHroKUg7J2M66Cl&enc=utf8§ion=kin&rank=1&search_sort=0&spq=0

 

댓글란에 보면 네이버의 달력에서 소스를 추출해 왔다고 한다. 실제로 적용해보면 음력으로 값이 잘 나오게 되고 음력날짜를 넣어 양력값을 얻는 부분도 type값만 바꿔주면 바로 얻을 수 있었다.

 

 

코드 분석을 시작하면 왠 이상한 2차원 배열을 볼 수 있다. 처음에는 이게 뭔가 싶었는데 자세히 보면 1과 2사이에 틈틈히 3 ~ 6까지의 숫자가 보인다. 이 3 ~ 6까지의 숫자를 처리하는 것이 중요하다. 음력도 양력처럼 윤년같은 개념이 존재한다. 근데 음력은 양력처럼 2월이 29일이 되는게 아니라 달이 한번 추가되어 1년이 13개월이 된다. 해당 배열에서는 1일때는 달의 총 일수가 29일이고 2일때는 30일, 3 ~ 6 일때는 해당 달이 한번 반복된다. 근데 또 반복될때 같은 총 일수로 반복되는게 아니라 3 ~ 6까지의 숫자마다 경우의 수가 다 다르다. 음달, 윤달이라는 명칭이 맞는지는 모르겠지만, 3일 경우 음달은 29일 윤달도 29일이고 4일 경우 음달은 29일 윤달은 30일이다. 5일 경우 음달은 30일 윤달은 29일, 6일 경우 음달은 30일 윤달도 30일이다. 아마도 이 모든 경우의 수를 처리하기위해 3 ~ 6까지의 숫자로 만든 것 같다.

 /*  음력 달력 배열
     음력은 모든 달이 29일 ~ 30일 으로만 이루어짐
     음력에도 윤달이 있을 경우 2월에 1일이 추가되는 식이 아니라
     한달이 추가되어짐
     1-> 29일, 2->30일
     3, 4, 5, 6은 윤달이 추가로 생성됨
     3-> 29일 + 윤29일, 4-> 29일 + 윤30일
     5-> 30일 + 윤29일, 6-> 30일 + 윤30일
 */
 const LUNAR_LAST_YEAR = 1939;
 var lunarMonthTable = [
 [2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 1, 2],
 [2, 2, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1],
 [2, 2, 1, 2, 2, 4, 1, 1, 2, 1, 2, 1],   /* 1941 */
 [2, 1, 2, 2, 1, 2, 2, 1, 2, 1, 1, 2],
 [1, 2, 1, 2, 1, 2, 2, 1, 2, 2, 1, 2],
 [1, 1, 2, 4, 1, 2, 1, 2, 2, 1, 2, 2],
 [1, 1, 2, 1, 1, 2, 1, 2, 2, 2, 1, 2],
 [2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2],
 [2, 5, 1, 2, 1, 1, 2, 1, 2, 1, 2, 2],
 [2, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2],
 [2, 2, 1, 2, 1, 2, 3, 2, 1, 2, 1, 2],
 [2, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 1],
 [2, 1, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2],   /* 1951 */

 

 

그 다음은 양력과 음력을 비교하여 값을 얻어내는 방식이다.

2000, 1970, 1940년도로 기준을 맞추고 입력한 년도가 그 범위값 안에 있으면 양력날짜와 음력날짜 값들을 초기화한다. 초기화 한 뒤 입력한 날짜와 양력 또는 음력날짜가 완전히 일치할 때 까지 1일씩 더해가면서 일치할 경우 해당 양력 또는 음력날짜를 반환한다. 

/* 속도 개선을 위해 기준 일자를 여러개로 한다 */
if (year >= 2000) {
    /* 기준일자 양력 2000년 1월 1일 (음력 1999년 11월 25일) */
    solYear = 2000;
    solMonth = 1;
    solDay = 1;
    lunYear = 1999;
    lunMonth = 11;
    lunDay = 25;
    lunLeapMonth = 0;

    solMonthDay[1] = 29;    /* 2000 년 2월 28일 */
    lunMonthDay = 30;   /* 1999년 11월 */
}
else if (year >= 1970) {
    /* 기준일자 양력 1970년 1월 1일 (음력 1969년 11월 24일) */
    solYear = 1970;
    solMonth = 1;
    solDay = 1;
    lunYear = 1969;
    lunMonth = 11;
    lunDay = 24;
    lunLeapMonth = 0;

    solMonthDay[1] = 28;    /* 1970 년 2월 28일 */
    lunMonthDay = 30;   /* 1969년 11월 */
}
else {
    /* 기준일자 양력 1940년 1월 1일 (음력 1939년 11월 22일) */
    solYear = 1940;
    solMonth = 1;
    solDay = 1;
    lunYear = 1939;
    lunMonth = 11;
    lunDay = 22;
    lunLeapMonth = 0;

    solMonthDay[1] = 29;    /* 1940 년 2월 28일 */
    lunMonthDay = 29;   /* 1939년 11월 */
}

lunIndex = lunYear - LUNAR_LAST_YEAR;

 

 

반복문의 상단에 반환하는 조건문이 있다. type이 1이면 양력날짜를, 2이면 음력날짜를 반환한다.

if (type == 1 &&
    year == solYear &&
    month == solMonth &&
    day == solDay) {
    return new myDate(lunYear, lunMonth, lunDay, lunLeapMonth);
}
else if (type == 2 &&
    year == lunYear &&
    month == lunMonth &&
    day == lunDay &&
    leapmonth == lunLeapMonth) {
    return new myDate(solYear, solMonth, solDay, 0);
}

 

 

그 다음 조건문인 양력에 날짜를 더하는 구문이다. 양력은 음력에 비해 굉장히 간단하다. 양력의 마지막날이면 년도를 증가시키고 월, 일을 1로 초기화, 그리고 해당 년도가 윤년일 경우 2월을 29일로 변경한다. 일수가 12월을 제외한 월의 마지막날과 일치하면 월을 증가시키고 일을 1로 초기화한다고 되어있다.

// 양력의 마지막 날일 경우 년도를 증가시키고 나머지 초기화
if (solMonth == 12 && solDay == 31) {
    solYear++;
    solMonth = 1;
    solDay = 1;

    // 윤년일 시 2월달의 총 일수를 1일 증가
    if (solYear % 400 == 0)
    	solMonthDay[1] = 29;
    else if (solYear % 100 == 0)
    	solMonthDay[1] = 28;
    else if (solYear % 4 == 0)
    	solMonthDay[1] = 29;
    else
    	solMonthDay[1] = 28;

}
// 현재 날짜가 달의 마지막 날짜를 가리키고 있을 시 달을 증가시키고 날짜 1로 초기화
else if (solMonthDay[solMonth - 1] == solDay) {
    solMonth++;
    solDay = 1;
}
else
	solDay++;

 

 

그 다음 조건문은 해당 함수의 마지막인 음력에 날짜를 더하는 구문이다. 먼저 양력과 마찬가지로 해당 음력의 마지막 날이면 년도를 증가시키고 월과 일을 1로 초기화 한다. 음력에서 특이한게 1월과 12월은 총 일수가 29일 아니면 30일로 구성되어 있다. 양력에서 윤년일 경우 2월을 29일로 바꿔준 것 처럼 음력에서는 월이 바뀔 때마다 총일수를 바꿔준다. 그 다음에는 반복되고있는 날짜가 달의 마지막날짜와 일치할 경우 조건처리를 많이 해줘야 한다. 소스의 맨 처음에 정의한 2차원 배열에서 값이 3이상이면 달이 한번 더 반복된다는 의미를 가지고 있는 변수 lunLeapMonth의 값을 1로 변경해주고 달의 수를 증가시키지 않는다. 그리고 일을 1로 초기화 하고 음달이거나 윤달을 계산한 경우라면 lunLeapMonth 값을 0으로 초기화하고 달과 일의 수를 1씩 증가시킨다. 그다음 많은 조건을 처리하는 조건문이 나오는데 이거는 그냥 위에서 말한 음력의 윤달에 대한 경우의 수를 처리하는 구문이다. 

// 음력의 마지막 날인 경우 년도를 증가시키고 달과 일수를 초기화
if (lunMonth == 12 &&
    ((lunarMonthTable[lunIndex][lunMonth - 1] == 1 && lunDay == 29) ||
    (lunarMonthTable[lunIndex][lunMonth - 1] == 2 && lunDay == 30))) {
    lunYear++;
    lunMonth = 1;
    lunDay = 1;

    if (lunYear > 2043) {
        alert("입력하신 달은 없습니다.");
        break;
    }

    // 년도가 바꼈으니 index값 수정
    lunIndex = lunYear - LUNAR_LAST_YEAR;

    // 음력의 1월에는 1 or 2만 있으므로 1과 2만 비교하면됨
    if (lunarMonthTable[lunIndex][lunMonth - 1] == 1)
    	lunMonthDay = 29;
    else if (lunarMonthTable[lunIndex][lunMonth - 1] == 2)
    	lunMonthDay = 30;
}
// 현재날짜가 이번달의 마지막날짜와 일치할 경우
else if (lunDay == lunMonthDay) {

    // 윤달인데 윤달계산을 안했을 경우 달의 숫자는 증가시키면 안됨
    if (lunarMonthTable[lunIndex][lunMonth - 1] >= 3
        && lunLeapMonth == 0) {
        lunDay = 1;
        lunLeapMonth = 1;
    }
    // 음달이거나 윤달을 계산 했을 겨우 달을 증가시키고 lunLeapMonth값 초기화
    else {
        lunMonth++;
        lunDay = 1;
        lunLeapMonth = 0;
    }

    // 음력의 달에 맞는 마지막날짜 초기화
    if (lunarMonthTable[lunIndex][lunMonth - 1] == 1)
    	lunMonthDay = 29;
    else if (lunarMonthTable[lunIndex][lunMonth - 1] == 2)
    	lunMonthDay = 30;
    else if (lunarMonthTable[lunIndex][lunMonth - 1] == 3)
    	lunMonthDay = 29;
    else if (lunarMonthTable[lunIndex][lunMonth - 1] == 4 &&
    	lunLeapMonth == 0)
    	lunMonthDay = 29;
    else if (lunarMonthTable[lunIndex][lunMonth - 1] == 4 &&
        lunLeapMonth == 1)
        lunMonthDay = 30;
    else if (lunarMonthTable[lunIndex][lunMonth - 1] == 5 &&
        lunLeapMonth == 0)
        lunMonthDay = 30;
    else if (lunarMonthTable[lunIndex][lunMonth - 1] == 5 &&
        lunLeapMonth == 1)
        lunMonthDay = 29;
    else if (lunarMonthTable[lunIndex][lunMonth - 1] == 6)
    	lunMonthDay = 30;
}
else
	lunDay++;

 

 

해당 코드로 간단하게 실험해 보면 음력으로 잘 변환되서 나온다.

양력값을 음력값으로 변환

 

 

전체 코드

더보기
<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <title>solar to lunar</title>
</head>

<body>
    <input type="text" id="year" maxlength="4">
    <input type="text" id="month" maxlength="2">
    <input type="text" id="day" maxlength="2">
    <button onclick="printDate();">solarToLunar</button>

    <script>
        function printDate(){
            var year = document.getElementById("year").value;
            var month = document.getElementById("month").value;
            var day = document.getElementById("day").value;

            alert(solarToLunar(year, month, day));
        }

        /*  음력 달력 배열
            음력은 모든 달이 29일 ~ 30일 으로만 이루어짐
            음력에도 윤달이 있을 경우 2월에 1일이 추가되는 식이 아니라
            한달이 추가되어짐
            1-> 29일, 2->30일
            3, 4, 5, 6은 윤달이 추가로 생성됨
            3-> 29일 + 윤29일, 4-> 29일 + 윤30일
            5-> 30일 + 윤29일, 6-> 30일 + 윤30일
        */
        const LUNAR_LAST_YEAR = 1939;
        var lunarMonthTable = [
            [2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 1, 2],   /* 양력 1940년 1월은 음력 1939년에 있음 그래서 시작년도는 1939년*/
            [2, 2, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1],
            [2, 2, 1, 2, 2, 4, 1, 1, 2, 1, 2, 1],   /* 1941 */
            [2, 1, 2, 2, 1, 2, 2, 1, 2, 1, 1, 2],
            [1, 2, 1, 2, 1, 2, 2, 1, 2, 2, 1, 2],
            [1, 1, 2, 4, 1, 2, 1, 2, 2, 1, 2, 2],
            [1, 1, 2, 1, 1, 2, 1, 2, 2, 2, 1, 2],
            [2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2],
            [2, 5, 1, 2, 1, 1, 2, 1, 2, 1, 2, 2],
            [2, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2],
            [2, 2, 1, 2, 1, 2, 3, 2, 1, 2, 1, 2],
            [2, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 1],
            [2, 1, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2],   /* 1951 */
            [1, 2, 1, 2, 4, 2, 1, 2, 1, 2, 1, 2],
            [1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 2, 2],
            [1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2],
            [2, 1, 4, 1, 1, 2, 1, 2, 1, 2, 2, 2],
            [1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2, 2],
            [2, 1, 2, 1, 2, 1, 1, 5, 2, 1, 2, 2],
            [1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2],
            [1, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1],
            [2, 1, 2, 1, 2, 5, 2, 1, 2, 1, 2, 1],
            [2, 1, 2, 1, 2, 1, 2, 2, 1, 2, 1, 2],   /* 1961 */
            [1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1],
            [2, 1, 2, 3, 2, 1, 2, 1, 2, 2, 2, 1],
            [2, 1, 2, 1, 1, 2, 1, 2, 1, 2, 2, 2],
            [1, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 2],
            [1, 2, 5, 2, 1, 1, 2, 1, 1, 2, 2, 1],
            [2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 1, 2],
            [1, 2, 2, 1, 2, 1, 5, 2, 1, 2, 1, 2],
            [1, 2, 1, 2, 1, 2, 2, 1, 2, 1, 2, 1],
            [2, 1, 1, 2, 2, 1, 2, 1, 2, 2, 1, 2],
            [1, 2, 1, 1, 5, 2, 1, 2, 2, 2, 1, 2],   /* 1971 */
            [1, 2, 1, 1, 2, 1, 2, 1, 2, 2, 2, 1],
            [2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 2, 1],
            [2, 2, 1, 5, 1, 2, 1, 1, 2, 2, 1, 2],
            [2, 2, 1, 2, 1, 1, 2, 1, 1, 2, 1, 2],
            [2, 2, 1, 2, 1, 2, 1, 5, 2, 1, 1, 2],
            [2, 1, 2, 2, 1, 2, 1, 2, 1, 2, 1, 1],
            [2, 2, 1, 2, 1, 2, 2, 1, 2, 1, 2, 1],
            [2, 1, 1, 2, 1, 6, 1, 2, 2, 1, 2, 1],
            [2, 1, 1, 2, 1, 2, 1, 2, 2, 1, 2, 2],
            [1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2],   /* 1981 */
            [2, 1, 2, 3, 2, 1, 1, 2, 2, 1, 2, 2],
            [2, 1, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2],
            [2, 1, 2, 2, 1, 1, 2, 1, 1, 5, 2, 2],
            [1, 2, 2, 1, 2, 1, 2, 1, 1, 2, 1, 2],
            [1, 2, 2, 1, 2, 2, 1, 2, 1, 2, 1, 1],
            [2, 1, 2, 2, 1, 5, 2, 2, 1, 2, 1, 2],
            [1, 1, 2, 1, 2, 1, 2, 2, 1, 2, 2, 1],
            [2, 1, 1, 2, 1, 2, 1, 2, 2, 1, 2, 2],
            [1, 2, 1, 1, 5, 1, 2, 1, 2, 2, 2, 2],
            [1, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 2],   /* 1991 */
            [1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2],
            [1, 2, 5, 2, 1, 2, 1, 1, 2, 1, 2, 1],
            [2, 2, 2, 1, 2, 1, 2, 1, 1, 2, 1, 2],
            [1, 2, 2, 1, 2, 2, 1, 5, 2, 1, 1, 2],
            [1, 2, 1, 2, 2, 1, 2, 1, 2, 2, 1, 2],
            [1, 1, 2, 1, 2, 1, 2, 2, 1, 2, 2, 1],
            [2, 1, 1, 2, 3, 2, 2, 1, 2, 2, 2, 1],
            [2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 2, 1],
            [2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1],
            [2, 2, 2, 3, 2, 1, 1, 2, 1, 2, 1, 2],   /* 2001 */
            [2, 2, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1],
            [2, 2, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2],
            [1, 5, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2],
            [1, 2, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1],
            [2, 1, 2, 1, 2, 1, 5, 2, 2, 1, 2, 2],
            [1, 1, 2, 1, 1, 2, 1, 2, 2, 2, 1, 2],
            [2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2],
            [2, 2, 1, 1, 5, 1, 2, 1, 2, 1, 2, 2],
            [2, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2],
            [2, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 1],   /* 2011 */
            [2, 1, 6, 2, 1, 2, 1, 1, 2, 1, 2, 1],
            [2, 1, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2],
            [1, 2, 1, 2, 1, 2, 1, 2, 5, 2, 1, 2],
            [1, 2, 1, 1, 2, 1, 2, 2, 2, 1, 2, 1],
            [2, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2],
            [2, 1, 1, 2, 3, 2, 1, 2, 1, 2, 2, 2],
            [1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2, 2],
            [2, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2],
            [2, 1, 2, 5, 2, 1, 1, 2, 1, 2, 1, 2],
            [1, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1],   /* 2021 */
            [2, 1, 2, 1, 2, 2, 1, 2, 1, 2, 1, 2],
            [1, 5, 2, 1, 2, 1, 2, 2, 1, 2, 1, 2],
            [1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1],
            [2, 1, 2, 1, 1, 5, 2, 1, 2, 2, 2, 1],
            [2, 1, 2, 1, 1, 2, 1, 2, 1, 2, 2, 2],
            [1, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 2],
            [1, 2, 2, 1, 5, 1, 2, 1, 1, 2, 2, 1],
            [2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2],
            [1, 2, 1, 2, 2, 1, 2, 1, 2, 1, 2, 1],
            [2, 1, 5, 2, 1, 2, 2, 1, 2, 1, 2, 1],   /* 2031 */
            [2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 2],
            [1, 2, 1, 1, 2, 1, 2, 1, 2, 2, 5, 2],
            [1, 2, 1, 1, 2, 1, 2, 1, 2, 2, 2, 1],
            [2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2],
            [2, 2, 1, 2, 1, 4, 1, 1, 2, 2, 1, 2],
            [2, 2, 1, 2, 1, 1, 2, 1, 1, 2, 1, 2],
            [2, 2, 1, 2, 1, 2, 1, 2, 1, 1, 2, 1],
            [2, 2, 1, 2, 5, 2, 1, 2, 1, 2, 1, 1],
            [2, 1, 2, 2, 1, 2, 2, 1, 2, 1, 2, 1],
            [2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 2],   /* 2041 */
            [1, 5, 1, 2, 1, 2, 1, 2, 2, 2, 1, 2],
            [1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2]];

        // 음력 계산을 위한 객체
        function myDate(year, month, day, leapMonth) {
            this.year = year;
            this.month = month;
            this.day = day;
            this.leapMonth = leapMonth;
        }

        // 양력을 음력으로 계산
        function lunarCalc(year, month, day, type, leapmonth) {
            var solYear, solMonth, solDay;
            var lunYear, lunMonth, lunDay;

            // lunLeapMonth는 음력의 윤달인지 아닌지를 확인하기위한 변수
            // 1일 경우 윤달이고 0일 경우 음달
            var lunLeapMonth, lunMonthDay;
            var i, lunIndex;

            var solMonthDay = [31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

            /* range check */
            if (year < 1940 || year > 2040) {
                alert('1940년부터 2040년까지만 지원합니다');
                return;
            }

            /* 속도 개선을 위해 기준 일자를 여러개로 한다 */
            if (year >= 2000) {
                /* 기준일자 양력 2000년 1월 1일 (음력 1999년 11월 25일) */
                solYear = 2000;
                solMonth = 1;
                solDay = 1;
                lunYear = 1999;
                lunMonth = 11;
                lunDay = 25;
                lunLeapMonth = 0;

                solMonthDay[1] = 29;    /* 2000 년 2월 28일 */
                lunMonthDay = 30;   /* 1999년 11월 */
            }
            else if (year >= 1970) {
                /* 기준일자 양력 1970년 1월 1일 (음력 1969년 11월 24일) */
                solYear = 1970;
                solMonth = 1;
                solDay = 1;
                lunYear = 1969;
                lunMonth = 11;
                lunDay = 24;
                lunLeapMonth = 0;

                solMonthDay[1] = 28;    /* 1970 년 2월 28일 */
                lunMonthDay = 30;   /* 1969년 11월 */
            }
            else {
                /* 기준일자 양력 1940년 1월 1일 (음력 1939년 11월 22일) */
                solYear = 1940;
                solMonth = 1;
                solDay = 1;
                lunYear = 1939;
                lunMonth = 11;
                lunDay = 22;
                lunLeapMonth = 0;

                solMonthDay[1] = 29;    /* 1940 년 2월 28일 */
                lunMonthDay = 29;   /* 1939년 11월 */
            }

            lunIndex = lunYear - LUNAR_LAST_YEAR;

            // type이 1일때는 입력받은 양력 값에 대한 음력값을 반환
            // 2일 때는 입력받은 음력 값에 대한 양력값을 반환
            // 반복문이 돌면서 양력 값들과 음력 값들을 1일 씩 증가시키고
            // 입력받은 날짜값과 양력 값이 일치할 때 음력값을 반환함
            while (true) {
                if (type == 1 &&
                    year == solYear &&
                    month == solMonth &&
                    day == solDay) {
                    return new myDate(lunYear, lunMonth, lunDay, lunLeapMonth);
                }
                else if (type == 2 &&
                    year == lunYear &&
                    month == lunMonth &&
                    day == lunDay &&
                    leapmonth == lunLeapMonth) {
                    return new myDate(solYear, solMonth, solDay, 0);
                }

                // 양력의 마지막 날일 경우 년도를 증가시키고 나머지 초기화
                if (solMonth == 12 && solDay == 31) {
                    solYear++;
                    solMonth = 1;
                    solDay = 1;

                    // 윤년일 시 2월달의 총 일수를 1일 증가
                    if (solYear % 400 == 0)
                        solMonthDay[1] = 29;
                    else if (solYear % 100 == 0)
                        solMonthDay[1] = 28;
                    else if (solYear % 4 == 0)
                        solMonthDay[1] = 29;
                    else
                        solMonthDay[1] = 28;

                }
                // 현재 날짜가 달의 마지막 날짜를 가리키고 있을 시 달을 증가시키고 날짜 1로 초기화
                else if (solMonthDay[solMonth - 1] == solDay) {
                    solMonth++;
                    solDay = 1;
                }
                else
                    solDay++;

                // 음력의 마지막 날인 경우 년도를 증가시키고 달과 일수를 초기화
                if (lunMonth == 12 &&
                    ((lunarMonthTable[lunIndex][lunMonth - 1] == 1 && lunDay == 29) ||
                        (lunarMonthTable[lunIndex][lunMonth - 1] == 2 && lunDay == 30))) {
                    lunYear++;
                    lunMonth = 1;
                    lunDay = 1;

                    if (lunYear > 2043) {
                        alert("입력하신 달은 없습니다.");
                        break;
                    }

                    // 년도가 바꼈으니 index값 수정
                    lunIndex = lunYear - LUNAR_LAST_YEAR;

                    // 음력의 1월에는 1 or 2만 있으므로 1과 2만 비교하면됨
                    if (lunarMonthTable[lunIndex][lunMonth - 1] == 1)
                        lunMonthDay = 29;
                    else if (lunarMonthTable[lunIndex][lunMonth - 1] == 2)
                        lunMonthDay = 30;
                }
                // 현재날짜가 이번달의 마지막날짜와 일치할 경우
                else if (lunDay == lunMonthDay) {

                    // 윤달인데 윤달계산을 안했을 경우 달의 숫자는 증가시키면 안됨
                    if (lunarMonthTable[lunIndex][lunMonth - 1] >= 3
                        && lunLeapMonth == 0) {
                        lunDay = 1;
                        lunLeapMonth = 1;
                    }
                    // 음달이거나 윤달을 계산 했을 겨우 달을 증가시키고 lunLeapMonth값 초기화
                    else {
                        lunMonth++;
                        lunDay = 1;
                        lunLeapMonth = 0;
                    }

                    // 음력의 달에 맞는 마지막날짜 초기화
                    if (lunarMonthTable[lunIndex][lunMonth - 1] == 1)
                        lunMonthDay = 29;
                    else if (lunarMonthTable[lunIndex][lunMonth - 1] == 2)
                        lunMonthDay = 30;
                    else if (lunarMonthTable[lunIndex][lunMonth - 1] == 3)
                        lunMonthDay = 29;
                    else if (lunarMonthTable[lunIndex][lunMonth - 1] == 4 &&
                        lunLeapMonth == 0)
                        lunMonthDay = 29;
                    else if (lunarMonthTable[lunIndex][lunMonth - 1] == 4 &&
                        lunLeapMonth == 1)
                        lunMonthDay = 30;
                    else if (lunarMonthTable[lunIndex][lunMonth - 1] == 5 &&
                        lunLeapMonth == 0)
                        lunMonthDay = 30;
                    else if (lunarMonthTable[lunIndex][lunMonth - 1] == 5 &&
                        lunLeapMonth == 1)
                        lunMonthDay = 29;
                    else if (lunarMonthTable[lunIndex][lunMonth - 1] == 6)
                        lunMonthDay = 30;
                }
                else
                    lunDay++;
            }
        }

        // 양력을 음력날짜로 변환
        function solarToLunar(solYear, solMonth, solDay) {
            // 날짜 형식이 안맞을 경우 공백 반환
            if (!solYear || solYear == 0 ||
                !solMonth || solMonth == 0 ||
                !solDay || solDay == 0) {
                return "";
            }

            // 양력의 달마다의 일수
            var solMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

            // 윤년일 시 2월에 1일 추가
            if (solYear % 400 == 0 || (solYear % 4 == 0 && solYear % 100 != 0)) solMonthDays[1] += 1;


            if (solMonth < 1 || solMonth > 12 ||
                solDay < 1 || solDay > solMonthDays[solMonth - 1]) {

                return "";
            }

            /* 양력/음력 변환 */
            var date = lunarCalc(solYear, solMonth, solDay, 1);

            return "음력 " + date.year + "년 " + (date.leapMonth ? "(윤)" : "") + date.month + "월 " + date.day;
        }
    </script>
</body>

</html>

 

 

응용하면 달력에 쉽게 표기도 할 수 있다.