⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lunar.js

📁 寿星万年历是一款采用现代天文算法制作的农历历算程序
💻 JS
📖 第 1 页 / 共 5 页
字号:
  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 + -