프로그래밍/html & jsp

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

Super User 2009. 6. 10. 14:51

이번에는 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