Skip to content

Instantly share code, notes, and snippets.

@Senarin
Created June 26, 2017 14:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Senarin/92e75b3e0c1507a83f78f2b373ad953e to your computer and use it in GitHub Desktop.
Save Senarin/92e75b3e0c1507a83f78f2b373ad953e to your computer and use it in GitHub Desktop.
Computus (Calculate Easter Sunday)
// 일반적인 양력이 아닌 1582년 이전의 날짜까지 포함한 그레고리력
var GregCal={
_EPOCH : 1721425.5,
isLeap : function(year){return ((year % 100) % 4 == 0) && (!(((year % 100) == 0) && ((year % 400) != 0)));},
cal2JD : function(year,month,day){
var JD=this._EPOCH-1;
JD+=365 * (year-1);
JD+=Math.floor((year-1) / 4);
JD+=-Math.floor((year-1) / 100);
JD+=Math.floor((year-1) / 400);
var adjust=(month <= 2) ? 0 : (this.isLeap(year) ? -1 : -2);
JD+=Math.floor((((367 * month)-362) / 12)+adjust+day);
return JD;
},
JD2cal : function(JD){
var TDays=Math.floor(JD-0.5)+0.5;
var depoch=TDays-this._EPOCH;
var qcent=Math.floor(depoch / 146097);
var dqcent=dmod(depoch,146097);
var cent=Math.floor(dqcent / 36524);
var dcent=dmod(dqcent,36524);
var quad=Math.floor(dcent / 1461);
var dquad=dmod(dcent,1461);
var yindex=Math.floor(dquad,365);
var year=(qcent * 400)+(cent * 100)+(quad * 4)+yindex;
if(!((cent == 4) || (yindex == 4))){year++;}
var yearday=TDays-this.cal2JD(year,1,1);
var leapadj=((TDays < this.cal2JD(year,3,1)) ? 0 : (this.isLeap(year) ? 1 : 2));
var month=Math.floor((((yearday+leapadj) * 12)+373) / 367);
var day=(TDays-this.cal2JD(year,month,1))+1;
return new Array(year,month,day);
}
};
// 일반적인 양력이 아닌 순수 율리우스력 계산
var JulianCal={
isLeap : function(year){return (dmod(year,4) == 0);},
cal2JD : function(year,month,day){
if(month <= 2){
year--;
month+=12;
}
return Math.floor(365.25 * (year+4716))+Math.floor(30.6001 * (month+1))+day-1524.5;
},
JD2cal : function(JD){
var numdays=Math.floor(JD+0.5);
var a=numdays;
var b=a+1524;
var c=Math.floor((b-122.1) / 365.25);
var d=Math.floor(c * 365.25);
var e=Math.floor((b-d) / 30.6001);
var month=(e < 14) ? (e-1) : (e-13);
var year=(month > 2) ? (c-4716) : (c-4715);
var day=b-d-Math.floor(30.6001 * e);
return new Array(year,month,day);
}
};
var d2Date={
days2Month : function(days,ytype){
if(days < 1){return Math.floor((days+ytype-3) / 30.6001)+3;}
if(days > 0){return Math.floor((days+30) / 30.6001)+2;}
},
days2Day : function(days,ytype){
var m=this.days2Month(days);
if(days < 1){return Math.floor(days+ytype-3-(30.6001 * m))+1;}
if(days > 0){return Math.floor(days+183-(30.6001 * (m+3)))+1;}
}
};
var easterCal={
dominicalLetters : ["A","B","C","D","E","F","G","BA","CB","DC","ED","FE","GF","AG"],
Epacts : ["*(XXX)","I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII","XIII","XIV","XV","XVI","XVII","XVIII","XIX","XX","XXI","XXII","XXIII","XXIV","XXV","XXVI","XXVII","XXVIII","XXIX"],
// 서방교회 (그레고리력 사용) 부활절 날짜
westernEaster : function(year){
var a=gmod(year,19);
var b=Math.floor(year / 100);
var c=gmod(year,100);
var d=Math.floor(b / 4);
var e=gmod(b,4);
var f=Math.floor((b+8) / 25);
var g=Math.floor((b-f+1) / 3);
var h=((19 * a)+b-d-g+15) % 30;
var i=Math.floor(c / 4);
var k=gmod(c,4);
var L=(32+(2 * e)+(2 * i)-h-k) % 7;
var m=Math.floor((a+(11 * h)+(22 * L)) / 451);
var eDays=h+L-(7 * m)+114;
var emonth=Math.floor(eDays / 31); // 월
var eday=1+(eDays % 31); // 일
// 윤년이 아닌지 검사
var isBissextile=GregCal.isLeap(year) ? 1 : 0;
/* 아래부터는 세부 정보 구하는 부분 */
var gn=a+1; // 황금 숫자 (Golden number)
var ep=gmod((11 * a)+8-b+d+Math.floor(((8 * b)+13) / 25),30);
// 주일 문자 (Dominical letter) 인수 계산
var dl0=((2 * (e+i))-k) % 7;
var dl=(dl0+7) % 7;
var df=dl+(7 * isBissextile);
// 성 금요일 (Good Friday) 날짜 계산
var daysmarch0=(31 * (emonth-3))+eday;
var gfmonth=d2Date.days2Month(daysmarch0-2,isBissextile);
var gfday=d2Date.days2Day(daysmarch0-2,isBissextile);
// 춘분 이후 첫 보름달 날짜 계산
var fmDays;
if(ep <= 23){fmDays=136-ep;}
else if(ep == 24 || ep == 25){fmDays=141;}
if(ep == 25 && gn > 11){fmDays=140;}
else if(ep >= 26){fmDays=166-ep;}
var fmonth=Math.floor(fmDays / 31);
var fday=1+(fmDays % 31);
// 부활절 때의 월령 계산
var lunaP=14+(eDays-fmDays);
return new Array(
[emonth,eday], // 부활절 날짜
[gfmonth,gfday], // 성 금요일 (Good Friday) 날짜
[fmonth,fday], // 춘분 이후 첫 보름달 날짜
[isBissextile,gn,ep,df,lunaP,daysmarch0] // 기타 세부정보
);
},
// 동방교회 (율리우스력 사용) 부활절 날짜
easternEaster : function(year){
var a=gmod(year,4);
var b=gmod(year,7);
var c=gmod(year,19);
var d=((19 * c)+15) % 30;
var e=((2 * a)+(4 * b)-d+34) % 7;
var emonth=Math.floor((d+e+114) / 31);
var eday=1+((d+e+114) % 31);
var JDeaster=JulianCal.cal2JD(year,emonth,eday);
var gmonth=GregCal.JD2cal(JDeaster)[1];
var gday=GregCal.JD2cal(JDeaster)[2];
return new Array(
[emonth,eday], // 원래 율리우스력 날짜
[gmonth,gday] // 그레고리력으로 환산한 날짜
);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment