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

📄 lunar.js

📁 寿星万年历 基于天文算法的万年历 javascript 年代范围大 精度高
💻 JS
📖 第 1 页 / 共 5 页
字号:
    n = this.QB.substr( Math.floor((jd-f2)/365.2422*24),1 ); //找定气修正值
   }else{
    D = Math.floor( this.so_low( Math.floor((jd+pc-2451551)/29.5306) * Math.PI*2 )     +0.5 ); //2451551是2000.1.7的那个朔日,黄经差为0.定朔计算
    n = this.SB.substr( Math.floor((jd-f2)/29.5306),1 ); //找定朔修正值
   }
   if(n=="1") return D+1;
   if(n=="2") return D-1;
   return D;
  }
 },

 //排月序(生成实际年历),在调用calcY()后得到以下数据
 //时间系统全部使用北京时,即使是天象时刻的输出,也是使用北京时
 //如果天象的输出不使用北京时,会造成显示混乱,更严重的是无法与古历比对
 leap:0,         //闰月位置
 ym:new Array(), //各月名称
 ZQ:new Array(), //中气表,其中.liqiu是节气立秋的儒略日,计算三伏时用到
 HS:new Array(), //合朔表
 dx:new Array(), //各月大小

 calcY:function(jd){ //农历排月序计算,可定出农历,有效范围:两个冬至之间(冬至一 <= d < 冬至二)
  var A=this.ZQ, B=this.HS;  //中气表,日月合朔表(整日)
  var i, k, W, w;

  //该年的中气
  W = int2( (jd-355+183)/365.2422 )*365.2422+355;  //355是2000.12冬至,得到较靠近jd的冬至估计值
  if(this.calc(W,'气')>jd) W-=365.2422;
  for(i=0;i<25;i++) A[i]=this.calc(W+15.2184*i,'气'); //25个节气时刻(北京时间),从冬至开始到下一个冬至以后
  A.pe1=this.calc(W-15.2,'气'); A.pe2=this.calc(W-30.4,'气'); //被算二气,确保一年中年有月份的“气”全部被计算在内

  //今年"首朔"的日月黄经差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();

/*********************************
以下是月历表的具体实现方法
*********************************/


/*********************************
=====以下是公历、农历、回历综合日历计算类=====

  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 月相节气表

**********************************/


//月历类件
function Lunar(){
 var i;
 this.lun=new Array();
 for(i=0;i<31;i++) this.lun[i] = new Object();
 this.lun.dn=0;

 this.substr2=function(s,n,end){ //截串(网页设计对过长的文字做截处理)
  s=s.replace(/(^\s*)|(\s*$)/g, "");
  if(s.length>n+1) return s.substr(0,n)+end;
  return s;
 };

 //返回公历某一个月的'公农回'三合历
 this.yueLiCalc=function(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];  //距小暑的天数

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -