📄 lunar.js
字号:
if(this.calc(W,'气')>jd) W-=365.2422;
for(i=0;i<25;i++) A[i]=this.calc(W+15.2184*i,'气'); //25个节气时刻(北京时间),从冬至开始到下一个冬至以后
//今年"首朔"的日月黄经差w
w = this.calc(A[0],'朔'); //求较靠近冬至的朔日
if(w>A[0]) w -= 29.53;
//该年所有朔,包含14个月的始末
for(i=0;i<15;i++) B[i]=this.calc(w+29.5306*i,'朔');
//月大小
this.leap = 0;
for(i=0;i<14;i++){
this.dx[i] = this.HS[i+1]-this.HS[i]; //月大小
this.ym[i]=i; //月序初始化
}
//-721年至-104年的后九月及月建问题,与朔有关,与气无关
var YY = int2( (this.ZQ[0]+10 +180)/365.2422) + 2000; //确定年份
if( YY>=-721 && YY <=-104 ){
var ly,b0,k0,lName,x0; //ly为历元(本历首月的儒略数),x0月建,lName闰月名称,b0,k0为置闰拟合参数
if(YY>=-721) ly=1457698-J2000, k0=12.368422, b0=0.342, lName='十三', x0=2; //春秋历,ly为-722.12.17
if(YY>=-479) ly=1546083-J2000, k0=12.368422, b0=0.500, lName='十三', x0=2; //战国历,ly为-480.12.11
if(YY>=-220) ly=1640641-J2000, k0=12.369000, b0=0.866, lName='后九', x0=11; //秦汉历,ly为-221.10.31;
nY = int2( (this.HS[0]-ly+100)/365.25 ); //年积数
var f1 = int2(b0+nY*k0), f2 = int2(b0+nY*k0+k0), f3; //f1有本年首的月积数,f2为下一年首的月积数
f1 = int2(f1); f2 = int2(f2);
for(i=0;i<14;i++){
f3 = int2( (this.HS[i]-ly+15)/29.5306 ); //该月积数
if(f3 < f2) f3 -= f1; else f3 -= f2;
if(f3 < 12) this.ym[i] = obb.ymc[(f3+x0)%12]; else this.ym[i] = lName;
}
return;
}
//无中气置闰法确定闰月,(气朔结合法,数据源需有冬至开始的的气和朔)
if( B[13] <= A[24] ){ //第13月的月末没有超过冬至(不含冬至),说明今年含有13个月
for(i=1; B[i+1]>A[2*i] && i<13; i++); //在13个月中找第1个没有中气的月份
this.leap = i;
for(;i<14;i++) this.ym[i]--;
}
//名称转换(月建别名)
for(i=0;i<14;i++){
var Dm = this.HS[i]+J2000, v2=this.ym[i]; //Dm初一的儒略日,v2为月建序号
var mc = obb.ymc[v2%12]; //月建对应的默认月名称:建子十一,建丑十二,建寅为正……
if ( Dm>=1724360 && Dm<=1729794 ) mc = obb.ymc[(v2+1)%12]; // 8.01.15至 23.12.02 建子为十二,其它顺推
else if( Dm>=1807724 && Dm<=1808699 ) mc = obb.ymc[(v2+1)%12]; //237.04.12至239.12.13 建子为十二,其它顺推
else if( Dm>=1999349 && Dm<=1999467 ) mc = obb.ymc[(v2+2)%12]; //761.12.02至762.03.30 建子为正月,其它顺推
else if( Dm>=1973067 && Dm<=1977112 ){if(v2%12==0) mc="正"; if(v2==2) mc='一';} //689.12.18至701.01.14 建子为正月,建寅为一月,其它不变
if(Dm==1729794||Dm==1808699) mc='拾贰'; //239.12.13及23.12.02均为十二月,为避免两个连续十二月,此处改名
this.ym[i]=mc;
}
}
};
SSQ.init();
function mingLiBaZi(jd,J,ob){ //命理八字计算。jd为格林尼治UT(J2000起算),J为本地经度,返回在物件ob中
var i, c, v;
var jd2 = jd+JD.deltatT2(jd); //力学时
var w = XL.S_aLon( jd2/36525, -1 ); //此刻太阳视黄经
var k = int2( (w/pi2*360+45+15*360)/30 ); //1984年立春起算的节气数(不含中气)
jd += XL.shiCha2(jd2/36525)-J/Math.PI/2; //本地真太阳时(使用低精度算法计算时差)
ob.bz_zty = JD.timeStr(jd);
jd += 13/24; //转为前一日23点起算(原jd为本日中午12点起算)
var D = Math.floor(jd), SC = int2( (jd-D)*12 ); //日数与时辰
v = int2(k/12+6000000); ob.bz_jn = obb.Gan[v%10]+obb.Zhi[v%12];
v = k+2+60000000; ob.bz_jy = obb.Gan[v%10]+obb.Zhi[v%12];
v = D - 6 + 9000000; ob.bz_jr = obb.Gan[v%10]+obb.Zhi[v%12];
v = (D-1)*12+90000000+SC;ob.bz_js = obb.Gan[v%10]+obb.Zhi[v%12];
v-= SC, ob.bz_JS = ''; //全天纪时表
for(i=0; i<13; i++){ //一天中包含有13个纪时
c = obb.Gan[(v+i)%10]+obb.Zhi[(v+i)%12]; //各时辰的八字
if(SC==i) ob.bz_js=c, c = '<font color=red>'+c+'</font>'; //红色显示这时辰
ob.bz_JS += (i?' ':'') + c;
}
}
/*********************************
以下是月历表的具体实现方法
*********************************/
/*********************************
=====以下是公历、农历、回历综合日历计算类=====
Lunar:日历计算物件
使用条件:事先引用eph.js天文历算文件
实例创建: var lun = new Lunar();
一、 yueLiCalc(By,Bm)方法
·功能:算出该月每日的详信息
·入口参数:
By是年(公历)
Bm是月(公历)
·返回:
lun.w0= (Bd0 + J2000 +1)%7; //本月第一天的星期
lun.y 公历年份
lun.m 公历月分
lun.d0 月首儒略日数
lun.dn 月天数
lun.Ly 干支纪年
lun.ShX 该年对应的生肖
lun.nianhao 年号纪年
lun.lun[] 各日信息(对象),日对象尊守此脚本程序开始的注释中定义
二、yueLiHTML(By,Bm)方法
·功能:算出该月每日的详细信息,并给出HTML月历表
·入口参数:
By是年(公历)
Bm是月(公历)
·返回:
yueLiCalc(By,Bm)返回的信息
lun.pg0 年份信息
lun.pg1 月历表
lun.pg2 月相节气表
**********************************/
//Lunar的成员函数
function yueLiCalc(By,Bm){ //返回公历某一个月的'公农回'三合历
var i,j,k,c,Bd0,Bdn;
//日历物件初始化
JD.h=12, JD.m=0, JD.s=0.1;
JD.Y=By; JD.M=Bm; JD.D=1; Bd0 = int2(JD.toJD()) - J2000; //公历月首,中午
JD.M++; if(JD.M>12) JD.Y++,JD.M=1; Bdn = int2(JD.toJD()) - J2000 - Bd0; //本月天数(公历)
this.w0= (Bd0 + J2000 +1)%7; //本月第一天的星期
this.y = By; //公历年份
this.m = Bm; //公历月分
this.d0 =Bd0;
this.dn= Bdn;
//所属公历年对应的农历干支纪年
c = By -1984 + 9000;
this.Ly = obb.Gan[c%10]+obb.Zhi[c%12]; //干支纪年
this.ShX = obb.ShX[c%12]; //该年对应的生肖
this.nianhao = obb.getNH(By);
var D,w,ob,ob2;
//提取各日信息
for(i=0,j=0;i<Bdn;i++){
ob = this.lun[i];
ob.d0 = Bd0+i; //儒略日,北京时12:00
ob.di = i; //公历月内日序数
ob.y = By; //公历年
ob.m = Bm; //公历月
ob.dn = Bdn; //公历月天数
ob.week0 = this.w0; //月首的星期
ob.week = (this.w0+i)%7; //当前日的星期
ob.weeki = int2((this.w0+i)/7); //本日所在的周序号
ob.weekN = int2((this.w0+Bdn-1)/7) + 1; //本月的总周数
JD.setFromJD(ob.d0+J2000); ob.d = JD.D; //公历日名称
//农历月历
if(!SSQ.ZQ.length || ob.d0<SSQ.ZQ[0] || ob.d0>=SSQ.ZQ[24]) //如果d0已在计算农历范围内则不再计算
SSQ.calcY(ob.d0);
var mk = int2( (ob.d0-SSQ.HS[0])/30 ); if(mk<13 && SSQ.HS[mk+1]<=ob.d0) mk++; //农历所在月的序数
ob.Ldi = ob.d0 - SSQ.HS[mk]; //距农历月首的编移量,0对应初一
ob.Ldc = obb.rmc[ob.Ldi]; //农历日名称
ob.cur_dz = ob.d0-SSQ.ZQ[0]; //距冬至的天数
ob.cur_xz = ob.d0-SSQ.ZQ[12]; //距夏至的天数
ob.cur_lq = ob.d0-SSQ.ZQ[15]; //距立秋的天数
ob.cur_mz = ob.d0-SSQ.ZQ[11]; //距芒种的天数
ob.cur_xs = ob.d0-SSQ.ZQ[13]; //距小暑的天数
if(ob.d0==SSQ.HS[mk]||ob.d0==Bd0){ //月的信息
ob.Lmc = SSQ.ym[mk]; //月名称
ob.Ldn = SSQ.dx[mk]; //月大小
ob.Lleap= (SSQ.leap&&SSQ.leap==mk)?'闰':''; //闰状况
ob.Lmc2 = mk<13?SSQ.ym[mk+1]:"未知"; //下个月名称,判断除夕时要用到
}else{
ob2=this.lun[i-1];
ob.Lmc = ob2.Lmc, ob.Ldn = ob2.Ldn;
ob.Lleap= ob2.Lleap, ob.Lmc2 = ob2.Lmc2;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -