본문 바로가기
프로그래밍/html & jsp

20줄 자바스크립트 1년 달력

by Super User 2009. 6. 10.

이번에는 1년치 달력을 한꺼번에 출력하는 소스입니다.
역시 1582년 10월 15일부터 4000년 1월까지 맞고, 버튼 등을 빼면 실제 달력 출력을
위한 부분은 20줄이 채 안됩니다.

http://alee.qubit.name/misc/calyear.html

<html>
<head>
<title>ALee's JavaScript Calendar</title>
<style type="text/css">
<!--
    td { font-family: Verdana, sans-serif; font-size: 9pt; text-align: center; }
    td.month { background-color: lightskyblue; border: solid 1px powderblue; }
    td.daytop { width: 18px; background-color: lemonchiffon; border: solid 1px powderblue; }
    td.weekday { color: darkblue; background-color: aliceblue; border: solid 1px powderblue; }
    td.holiday { color: crimson; background-color: linen; border: solid 1px powderblue; }
    span.arrow1 { font-family: Gulim, sans-serif; color: dodgerblue; cursor: pointer; }
    span.arrow2 { font-family: Gulim, sans-serif; color: blue; cursor: pointer; }
    span.arrow3 { font-family: Gulim, sans-serif; color: mediumblue; cursor: pointer; }
-->
</style>
<script language="JavaScript">
<!--
    function showYear(y) {
        var text = '<table>\n<tr><td colspan="4">';
        text += '<span class="arrow3" onclick="showYear('+(y-100)+')"> -100 </span>';
        text += '<span class="arrow2" onclick="showYear('+(y-10)+')"> -10 </span>';
        text += '<span class="arrow1" onclick="showYear('+(y-1)+')"> -1 </span>';
        text += ' ' + y + ' ';
        text += '<span class="arrow1" onclick="showYear('+(y+1)+')"> +1 </span>';
        text += '<span class="arrow2" onclick="showYear('+(y+10)+')"> +10 </span>';
        text += '<span class="arrow3" onclick="showYear('+(y+100)+')"> +100 </span>';
        text += '</td>';

        var d1, d2 = y+(y-1-(y-1)%4)/4-(y-1-(y-1)%100)/100+(y-1-(y-1)%400)/400;
        for (m = 1; m < 13; m++) {
            d1 = d2%7;
            d2 = d1+(m*9-m*9%8)/8%2+(m==2?y%4||y%100==0&&y%400?28:29:30);
            if (m%4 == 1) text += '</tr>\n<tr>';
            text += '<td><table>\n<tr><td class="month" colspan="7">' + m;
            for (i = 0; i < 42; i++) {
                if (i%7==0) text += '</tr>\n<tr>';
                if (i < d1 || i >= d2) text += '<td> </td>';
                else text += '<td class="'+(i%7?'week':'holi')+'day">'+(i+1-d1)+'</td>';
            }
            text += '</tr>\n</table></td>';
        }
        document.getElementById('calendarDiv').innerHTML = text + '</tr>\n</table>';
    }
-->
</script>
</head>
<body onload="showYear(2006)">
<div id="calendarDiv"></div>
</body>
</html>

 

-- 데모 화면

 

 2006년
1월
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
2월
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28
3월
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
4월
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
5월
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
6월
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30
7월
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
8월
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
9월
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
10월
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
11월
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
12월
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
 
 
이전 게시물 설명추가분
----------------------------------------------------------------------------------------이곳 팁텍 게시판에 이미 달력 소스가 여러번 올라왔지만,
간단하게 구현된 자바스크립트 달력이 없는 것 같아서 올립니다.
showCalendar() 함수에서 버튼 같은 것을 빼면 실제 달력을 그리는 데 필요한 부분은
10줄도 채 안 됩니다.

아마 그레고리력이 시행된 1582년 10월 15일부터 4000년 1월까지 맞을껍니다.
현재는 그레고리력을 수정해서 4000년, 8000년 등이 윤년이 아닌 평년이기 때문에
4000년 이후로는 안 맞습니다. 물론 약간만 수정하면 맞출 수 있지만 그 이후의 달력이
필요한 분은 없을꺼라 생각하고 그냥 올립니다.

http://alee.qubit.name/misc/calendar.html

<html>
<head>
<script language="JavaScript">
function showCalendar(y, m) {
    var text = '<table>\n<tr><td colspan=7 style="text-align:center">';
    text += '<span onclick="showCalendar('+(y-1)+','+m+')"> Y- </span>';
    text += '<span onclick="showCalendar('+(m==1?(y-1)+','+12:y+','+(m-1))+')"> M- </span>';
    text += '[' + y + '/' + ((m < 10) ? ('0' + m) : m) + ']';
    text += '<span onclick="showCalendar('+(m==12?(y+1)+','+1:y+','+(m+1))+')"> M+ </span>';
    text += '<span onclick="showCalendar('+(y+1)+','+m+')"> Y+ </span>';
    text += '</td>';

    var d1 = (y+(y-y%4)/4-(y-y%100)/100+(y-y%400)/400
          +m*2+(m*5-m*5%9)/9-(m<3?y%4||y%100==0&&y%400?2:3:4))%7;
    for (i = 0; i < 42; i++) {
        if (i%7==0) text += '</tr>\n<tr>';
        if (i < d1 || i >= d1+(m*9-m*9%8)/8%2+(m==2?y%4||y%100==0&&y%400?28:29:30))
            text += '<td> </td>';
        else
            text += '<td' + (i%7 ? '' : ' style="color:red;"') + '>' + (i+1-d1) + '</td>';
    }
    document.getElementById('calendarDiv').innerHTML = text + '</tr>\n</table>';
}
</script>
</head>
<body onload="showCalendar(2006,8)">
<div id="calendarDiv" style="font-family:Gulim;font-size:9pt;"></div>
</body>
</html>

소스 설명을 조금 하자면,

y-1+(y-1-(y-1)%4)/4-(y-1-(y-1)%100)/100+(y-1-(y-1)%400)/400
은 (1년부터 (y-1)년까지의 각 해의 날짜 수 - 364)를 모두 더한 것이고,

m*2+(m*5-m*5%9)/9-(m>2?y%4||y%100==0&&y%400?4:3:2)
은 (y년 1월부터 y년 (m-1)월까지 각 월의 날짜 수 - 28)을 모두 더한 것입니다.

그런데 364=7*52, 28=7*4 이므로 364나 28을 더하거나 빼도 7로 나눈
나머지에는 변함이 없습니다. 즉, 위의 두 줄을 더한 값을 7로 나눈 나머지는,
1년 1월 1일부터 y년 (m-1)월 말일까지의 날짜 수를 7로 나눈 나머지와 같습니다.

따라서 위의 두 식을 더한 다음 7로 나눈 나머지를 구하면 y년 m월 1일이 무슨 요일인지
알 수 있습니다. 다시 말해서 각 요일에 따라서 0~6 사이의 숫자가 나옵니다. 그런데
y=2006, m=1을 집어넣어 보면 6이 나옵니다. 따라서 실제 2006년 1월 1일은
일요일이므로, 식의 결과가 6이 나오면 일요일, 0이 나오면 월요일, 1이 나오면 화요일···
등이라는 것을 알 수 있습니다.

그런데 6=일, 0=월, 1=화··· 보다는 0=일, 1=월, 2=화··· 이렇게 한칸씩 쉬프트하는
것이 좀 더 사용하기 편리합니다. 이렇게 요일을 나타내는 숫자를 1씩 쉬프트하기
위해서는 전체 식을 7로 나누기 전에 1을 더해주면 되는데, 운좋게도 식 첫 부분에
y-1이 있으므로 y-1 대신 그냥 y를 쓰면 됩니다. 이렇게 해서,

(y+(y-1-(y-1)%4)/4-(y-1-(y-1)%100)/100+(y-1-(y-1)%400)/400
 +m*2+(m*5-m*5%9)/9-(m>2?y%4||y%100==0&&y%400?4:3:2))%7;
을 계산하면 y년 m월 1일의 요일(0=일요일, 1=월요일···)을 구할 수 있습니다.
소스에서 var d1 = 으로 시작하는 줄은 위의 식을 조금 더 압축한 것입니다.

또, 소스의 for문 안쪽에서 두번째 if절의
(m*9-m*9%8)/8%2+(m==2?y%4||y%100==0&&y%400?28:29:30)
은 y년 m월의 날짜 수입니다.
 
 
출처 : phpSchool