QuizWit

[알림판목록 I] [알림판목록 II] [글목록][이 전][다 음]
[ QuizWit ] in KIDS
글 쓴 이(By): limelite (깜찍이중독)
날 짜 (Date): 2000년 1월 30일 일요일 오전 03시 26분 30초
제 목(Title): 정말뒷북: 요일계산 ^^


  굉장히 뒷북이네요. ^^ 간단히 요일 계산하는데는 Zeller's formula면
충분합니다만, 위에 y2k 문제니 1753년 영국력이니 하는 이야기가 나와서
좀 더 자세히 적어 봅니다.
  요일 계산을 좀 더 formal하게 하면 Julian Day(JD)를 이용합니다.
JD에 대해서 제가 가지고 있는 "역법의 원리분석"이라는 책을 참조해서
적으면, B.C. 4713년1월0일 12시를 0.0일로 해서 하루에 1씩 증가하는
일련번호를 붙이는 것입니다. 그러니까, JD는 B.C.4713년1월1일부터
특정일까지의 경과일수를 의미하게 됩니다. JD는 정수부 외에 소숫점 아래
소수부도 가지고 있는데, 이 소수부는 12시부터의 경과시간을 의미
합니다. 이렇게 해서, JD는 천체운동 계산하는 데 사용되는 등 많은
용도로 이용됩니다.
  요일 계산 같은 것은 JD의 정수부만 사용하는데, JD의 정수부만 이용해도
그것을 7로 나눈 나머지로 요일을 계산한다거나, 60으로 나눈 나머지로
중국력의 일진을 계산하는 등 1일을 단위로 주기적으로 일어나는 사건들을
계산하기 쉽게 해 줍니다. JD정수부의 또 다른 이용 예로, 두 날짜의 JD를
구하면 그 차를 구해 두 날짜 사이의 날수를 쉽게 알 수 있지요.

  서양의 태양력을 JD로 변환하는데는 위에도 잠깐 언급되었듯이 서양
태양력의 역사와 관련해서 약간의 문제가 있습니다. B.C. 40년 경에
로마에서 사용되기 시작한 율리우스력이 기원 후에 겨우 현재와 비슷하게
안정되었고, 16세기에는 윤년 규칙을 개정한 그레고리력으로 바뀌었지요.
(1582년10월4일 다음 날을 10월15일로 정해서 10일을 끊어냄) 근데, 이
그레고리력의 도입 시기가 국가별로 달랐습니다. 로마황제의 성미에 따라
달의 이름과 길이들을 마음대로 바꾸던 서양 사람들이 이번에는 또 종교
교리 논쟁과 혼동하여 채택을 거부했기 때문이라는데요. 1582년에 개정
되었을 때는 이탈리아와 그 근방 국가들이 그레고리력을 사용하기 시작
했다가, 1700년 경에 독일과 네덜란드 덴마아크 등으로 퍼졌고, 영국이
서유럽 국가 중에는 가장 늦게 1752년부터, 러시아는 혁명 후인 1918년에
사용하기 시작했다고 합니다. 여기에 추가로, 그레고리력의 새로운 윤년
규칙도 잘 알려져 있다시피 태양년과 비교해 약간의 오차를 발생시키기
때문에, 이에 대한 현대적인 보정도 가해졌습니다.
  물론, 이런 문제들은 현대의 우리 양력을 보면서 요일을 계산하는데
큰 의미가 있는 것은 아니고, 좀 더 완벽하고 넓은 시간 범위에서
성립하는 계산을 바랄 때만 의미가 있겠지요.

  서양태양력일의 JD 변환 공식은 여러가지가 있는데, 먼저 서양력의
윤년 계산법을 고려해야 합니다. 서양력의 윤년은

  율리우스력 : 년도가 4로 나누어 떨어지는 해
               (1년길이 = 365.25일)
  그레고리력 : 년도가 4로 나누어 떨어지면서 100으로 나누어 떨어지지
               않는 해와, 400으로 나누어 떨어지는 해
               (1년길이 = 356.2425일)
  현대       : 그레고리력 윤년에서 4000으로 나누어 떨어지는 해를
               제외한 해

로 정해집니다.
  먼저 이해하기 쉽게 그레고리력을 기준으로 JD를 구하는 식을 "역법의
원리분석"을 참조해 적어보면...

JD = 36524*c + int(c/4)                : 세기항
   + 365*n + int(n/4)                  : 년항
   + 30*m + int((3*m-7)/5)             : 월항
   + d                                 : 일항
   + K                                 : 상수항

여기서...

   y = 계산할 날의 년도 = 100*c + n, 0<=n<=99, 16<=c<=39
   m = 계산할 날의 월, 3<=m<=14
   d = 계산할 날의 일자
   K = JD 상수

특기할 것은 월항의 계산인데, 먼저 2월말이 28일이 되기도 하고 29일이
되기도 하므로 계산을 간단히 하기 위해 1월 2월을 전년에 붙이고 1월은
13월, 2월은 14월로 계산합니다. 해당 월까지의 날수는 각 월의 날수를
기본 30일로 하고 int((3*m-7)/5)와 같은 보정항을 더해 계산합니다.
  윗 식의 여러가지 변형이 가능한데, 먼저 세기항과 년항을 약간 바꿀
수 있습니다.

JD = int(36524.25*c) + int(365.25*n) + ...

혹은, 실수 계산을 피하기 위해...

JD = int(146097*c/4) + int(1461*n/4) + ...

그 밖에 월항 계산법도 약간씩 바꿀 수 있고요. 인터넷에 보면은 여러가지
공식을 이용해 JD를 구하고 다시 요일을 구한다던가 하는데요. 그런
공식들이 모두 이렇게 얻어진 것입니다.

  여러 JD 계산 공식들이 대부분 그레고리력을 기준으로 만들어졌기 때문에,
율리우스력을 위해서는 다시 공식을 만든다거나(그레고리력보다는 단순
하겠지만), A.D.4000년이 윤년이 아니고 평년이라는 점 등을 반영하기
곤란합니다. 이런 점을 피하기 위해, 전에 제가 만세력을 만들 때는 다른
공식을 만들어 사용했습니다. 이 공식을 c 언어의 정수계산 식으로
표현하면...

 i  = (month+9) % 12;                   // 2월이 1년의 끝이 되도록
 y  = year - (i+2)/12;                  // 년도와 월을 다시 계산.

 jd = (1461*y) / 4                      // 년항 (세기항 없음)
    + (153*i+2) / 5                     // 월항
    + date + K                          // 일항 및 상수항
                                        // jd = 율리우스력 JD
 if( Gregorian_Calendar )
    jd += -y/100 + y/400 - y/4000 + 2;  // 그레고리력인 경우 보정

이런 공식이면, 율리우스력인지 그레고리력인지만 구분해 주면 대략 A.D.
9년 이후부터는 JD를 구할 수 있습니다.
  한편, 현재 사용하기 적합하게 적용범위를 줄여서 좀 더 간단한 식을
만들 수도 있습니다. 1900.3.1 ~ 2100.2.28까지를 적용 범위로 삼는다면,
이 기간의 윤년 배치가 율리우스력의 윤년 배치와 같음을 이용해서...

  month = (month+9) % 12;
  year -= (month+2) / 12;
  jd = (1461*year) / 4
     + (153*month+2) / 5
     + date + K;

이것만 사용해도, 3.1절이 무슨 요일이었는지, 오늘이 여자친구를 만난지
몇일째 되는 날인지 등의 계산에 유용하게 사용할 수 있지요. ^^

                                          어떻게 중독됐니?

                                          몽라 우어낙 숭시가네 일이라성 @_@

[알림판목록 I] [알림판목록 II] [글 목록][이 전][다 음]
키 즈 는 열 린 사 람 들 의 모 임 입 니 다.