<script language=javascript>
function int2(v){ return Math.floor(v);}
var JD={ //日期元件
Y:2000, M:1, D:1, h:12, m:0, s:0,
toJD:function(){ //公历转儒略日
var y=this.Y, m=this.M, n=0; //取出年月
if(m<=2) m+=12,y--;
if(this.Y*372+this.M*31+this.D>=588829)//判断是否为格里高利历日1582*372+10*31+15
n =int2(y/100), n =2-n+int2(n/4);//加百年闰
n +=int2(365.25*(y+4716)+0.01); //加上年引起的偏移日数
n +=int2(30.6*(m+1))+this.D; //加上月引起的偏移日数及日偏移数
n +=((this.s/60+this.m)/60+this.h)/24 - 1524.5;
return n;
},
setFromJD:function(jd){ //儒略日数转公历
jd+=0.5;
var A=int2(jd), F=jd-A, D; //取得日数的整数部份A及小数部分F
if(A>=2299161) D=int2((A-1867216.25)/36524.25),A+=1+D-int2(D/4);
A +=1524; //向前移4年零2个月
this.Y =int2((A-122.1)/365.25);//年
D =A-int2(365.25*this.Y); //去除整年日数后余下日数
this.M =int2(D/30.6001); //月数
this.D =D-int2(this.M*30.6001);//去除整月日数后余下日数
this.Y-=4716; this.M--;
if(this.M>12) this.M-=12;
if(this.M<=2) this.Y++;
//日的小数转为时分秒
F*=24; this.h=int2(F); F-=this.h;
F*=60; this.m=int2(F); F-=this.m;
F*=60; this.s=F;
},
toStr:function(){ //日期转为串
var Y=" "+this.Y,M="0"+this.M, D="0"+this.D;
var h=this.h,m=this.m,s=int2(this.s+.5);
if(s>=60) s-=60,m++;
if(m>=60) m-=60,h++;
h="0"+h; m="0"+m; s="0"+s;
Y=Y.substr(Y.length-5,5); M=M.substr(M.length-2,2); D=D.substr(D.length-2,2);
h=h.substr(h.length-2,2); m=m.substr(m.length-2,2); s=s.substr(s.length-2,2);
return Y+"-"+M+"-"+D+" "+h+":"+m+":"+s;
}
};
var gan=Array("甲","乙","丙","丁","戊","己","庚","辛","壬","癸");
gan['甲']=0;gan['乙']=1;gan['丙']=2;gan['丁']=3;gan['戊']=4;
gan['己']=5;gan['庚']=6;gan['辛']=7;gan['壬']=8;gan['癸']=9;
function getsjb(lun,nd,ra,rb){//取数据表
var i,j,k,p,c,v,jn;
var n1=-1,n2=-1;
nd=nd.split(" "); for(i=0;i<6;i++) nd[i]-=0; if(!nd[6]) nd[6]="";
for(i=0;i<lun.length;i++){
if(lun[i].substr(0,2)!="年份") continue;
v=lun[i].substr(2,5);
if(v==nd[0]) n1=i;
if(v==nd[3]){n2=i; break;}
}
if(n1==-1||n2==-1) return "年代中的年份参数有误";
n1 += nd[1], n2 += nd[4];
ra.length=rb.length=0;
//提取朔日和节气
for(i=0,k=0,p=0;i<=n2-n1;i++){
v=lun[i+n1]; if(v.substr(0,2)=="年份") continue;
v=v.split(" ");
ra[p++]=v[1]; //月大小
j=3,jn=v.length; //节气行内始终
if(i==0) j=nd[2]+3-1;
if(i==n2-n1) { jn=nd[5]+3; if(jn>v.length) jn=v.length; }
for(;j<jn;j++) rb[k++]=v[j];
if(!i){
//朔起始日期
ra.lifa=nd[6]; //历法名称
JD.Y=nd[0]-0; JD.M=v[2].substr(0,2)-0; JD.D=v[2].substr(2,2)-0; JD.h=12; JD.m=JD.s=0;
if(nd[1]<6&&ra.M>8) JD.Y--;
if(nd[1]>7&&ra.M<6) JD.Y++;
ra.jd=JD.toJD();
ra.rq0 = JD.toStr().substr(0,11);
ra.n0 =Math.floor((ra.jd+10-2451545)/29.5306);
//节气起始日期
var x=rb[0].substr(0,2),xx=0;
if(x=="一日") xx=1; if(x=="二日") xx=2; if(x=="三日") xx=3; if(x=="四日") xx=4; if(x=="五日") xx=5;
if(x=="六日") xx=6; if(x=="七日") xx=7; if(x=="八日") xx=8; if(x=="九日") xx=9; if(x=="十日") xx=10;
if(x=="十一") xx=11;if(x=="十二") xx=12;if(x=="十三") xx=13;if(x=="十四") xx=14;if(x=="十五") xx=15;
if(x=="十六") xx=16;if(x=="十七") xx=17;if(x=="十八") xx=18;if(x=="十九") xx=19;if(x=="二十") xx=20;
if(x=="廿一") xx=21;if(x=="廿二") xx=22;if(x=="廿三") xx=23;if(x=="廿四") xx=24;if(x=="廿五") xx=25;
if(x=="廿六") xx=26;if(x=="廿七") xx=27;if(x=="廿八") xx=28;if(x=="廿九") xx=29;if(x=="三十") xx=30;
rb.jd = ra.jd+xx-1;
JD.setFromJD(rb.jd);
rb.rq0 = JD.toStr().substr(0,11);
rb.n0 = Math.floor((rb.jd+6-2451545+292)/365.2422*24);
}
}
//历月处理
for(i=ra.length-1;i>0;i--)
if(ra[i-1]=="大") ra[i]=30; else ra[i]=29;
ra[0]=0;
for(i=1;i<ra.length;i++) ra[i]+=ra[i-1];
//节气处理
for(i=0;i<rb.length;i++) rb[i]=gan[rb[i].substr(2,1)];
for(i=rb.length-1;i>0;i--){
v=rb[i]-rb[i-1];
if(v<0) v+=10;
if(v<10) v+=10;
rb[i]=v;
}
rb[0]=0;
for(i=1;i<rb.length;i++) rb[i]+=rb[i-1];
}
//平气朔处理
function nihe(r){//拟合计算
var b=0;
var k=365.2422/24; if(r[1]-r[0]>23) k=29.5306; //斜率
var i,j,kk,v;
var k1=k-0.3,k2=k+0.3;
for(kk=0;kk<12;kk++){ //查找次数
var bm=-1000,bM=1000,bmi=-1;
for(i=0;i<r.length;i++){
v=r[i]-(k*i+b); //直线至少要上移的量
if(v>bm) bm=v,bmi=i;
if(v<bM) bM=v;
}
var h=(bM+1-bm)/2;
if(h>-1e-7){ b+=bm+h; r.gk = k; r.gb = b; r.gh = h; return "ok"; }
for(i=0;i<r.length;i++){
if(i==bmi) continue;
v=( r[i]+1 - r[bmi] ) / (i-bmi);
if(i<bmi && v>k1) k1=v;
if(i>bmi && v<k2) k2=v;
if(k1>k2) return "无解";
}
k=(k1+k2)/2;
b=r[bmi]-k*bmi;
}
return "查找"+kk+"次未找到解";
}
function calc(){
var i,j,c="",C="",c2,c3,c4, se=0,qe=0;
var ra=new Array(), rb=new Array();
var nd=fen.innerText, lun=nlb.innerText;
nd =nd.split("\r\n"); //年代分段表
lun=lun.split("\r\n"); //农历表
for(i=0;i<nd.length;i++){
if(!nd[i]) continue;
getsjb(lun,nd[i],ra,rb);
if(rb.jd<1947158){// 619-01-11,平朔结束
c2=nihe(ra);
if(c2=="ok") c += (ra.jd-0.5+ra.gb).toFixed(6)+","+ra.gk.toFixed(8)+", //"+ra.rq0+" h="+ra.gh.toFixed(5)+" "+ ra.lifa+"\r\n"; else c += "//"+ra.rq0+c2+"\r\n" ;
if(c2=="ok") se = (ra.jd-0.5+ra.gb+ra.gk*ra.length).toFixed(2);
}
c3=nihe(rb); if(c3=="ok") c4 = " 回归年="+(rb.gk*24).toFixed(5);
if(c3=="ok") C += (rb.jd-0.5+rb.gb).toFixed(6)+","+rb.gk.toFixed(8)+", //"+rb.rq0+" h="+rb.gh.toFixed(5)+" "+ ra.lifa+c4+"\r\n"; else C += "//"+ra.rq0+c2+"\r\n";
if(c3=="ok") qe = (rb.jd-0.5+rb.gb+rb.gk*rb.length).toFixed(2);
}
JD.setFromJD(se-0); c+=se+"//"+JD.toStr().substr(0,11)+"\r\n";
JD.setFromJD(qe-0); C+=qe+"//"+JD.toStr().substr(0,11)+"\r\n";
var c0="//气朔日期计算公式:D = k*n + b , 式中n=0,1,2,3,...,N-1\r\n";
c0+="//h表示k不变b允许的误差,如果b不变则k许可误差为h/N\r\n";
c0+="//每行第1个参数为b,第2参数为b\r\n\r\n";
out.innerText=c0+"//朔直线拟合参数\r\n"+c+"//气直线拟合参数\r\n"+C;
}
//定气朔处理
function suo_low(W){ //低精度定朔计算,在2000年至600,误差在2小时以内
var v = 7771.37714500204;
var t = ( W + 1.08472 )/v, L;
t -= ( -0.0000331*t*t
+ 0.10976 *Math.cos( 0.785 + 8328.6914*t)
+ 0.02224 *Math.cos( 0.187 + 7214.0629*t)
- 0.03342 *Math.cos( 4.669 + 628.3076*t ) )/v
+ (32*(t+1.8)*(t+1.8)-20)/86400/36525;
return t*36525 + 2451545;
}
function qi_low(W){ //最大误差小于30分钟,平均5分
var t,L,v= 628.3319653318;
t = ( W - 4.895062166 )/v; //第一次估算,误差2天以内
t -= ( 53*t*t + 334116*Math.cos( 4.67+628.307585*t) + 2061*Math.cos( 2.678+628.3076*t)*t )/v/10000000; //第二次估算,误差2小时以内
L = 48950621.66 + 6283319653.318*t + 53*t*t //平黄经
+334166 * Math.cos( 4.669257+ 628.307585*t) //地球椭圆轨道级数展开
+3489 * Math.cos( 4.6261 + 1256.61517*t ) //地球椭圆轨道级数展开
+2060.6 * Math.cos( 2.67823 + 628.307585*t ) * t //一次泊松项
- 994 - 834*Math.sin(2.1824-33.75705*t); //光行差与章动修正
t -= (L/10000000 -W )/628.332 + (32*(t+1.8)*(t+1.8)-20)/86400/36525;
return t*36525 + 2451545;
}
function yasuo(s){
s=s.replace(/0{60}/g,'A'); s=s.replace(/0{50}/g,'B');
s=s.replace(/0{40}/g,'C'); s=s.replace(/0{30}/g,'D');
s=s.replace(/0{20}/g,'E'); s=s.replace(/0{10}/g,'F');
s=s.replace(/0{9}1/g,'a');
s=s.replace(/0{8}1/g,'b');
s=s.replace(/0{7}1/g,'c');
s=s.replace(/0{6}1/g,'d');
s=s.replace(/0{5}1/g,'e');
s=s.replace(/00001/g,'f');
s=s.replace(/0001/g,'g');
s=s.replace(/001001/g,'h');
s=s.replace(/001/g,'i');
s=s.replace(/0101/g,'j');
s=s.replace(/01/g,'k');
s=s.replace(/0{9}2/g,'l');
s=s.replace(/0{8}2/g,'m');
s=s.replace(/0{7}2/g,'n');
s=s.replace(/0{6}2/g,'o');
s=s.replace(/0{5}2/g,'p');
s=s.replace(/0{4}2/g,'q');
s=s.replace(/0{3}2/g,'r');
s=s.replace(/0{2}2/g,'s');
s=s.replace(/02/g,'t');
s=s.replace(/0{5}/g,