【转】阳历转换阴历的换算方法(经过部分修改,现在能显示得正确)

网上有一个很经典的算法,可以计算出阳历时间对应的阴历时间,据测试在春节之前的时间,但是又过了元旦,那个时间段显示不正确,对此进行了修正。在此跟大家分享。已经全部注释好了。对此算法有更高见解的达人还请多多指教!~
 
 
   
var lunarInfo = new Array(
0x04bd8 , 0x04ae0 , 0x0a570 , 0x054d5 , 0x0d260 , 0x0d950 , 0x16554 , 0x056a0 , 0x09ad0 , 0x055d2 ,
0x04ae0 , 0x0a5b6 , 0x0a4d0 , 0x0d250 , 0x1d255 , 0x0b540 , 0x0d6a0 , 0x0ada2 , 0x095b0 , 0x14977 ,
0x04970 , 0x0a4b0 , 0x0b4b5 , 0x06a50 , 0x06d40 , 0x1ab54 , 0x02b60 , 0x09570 , 0x052f2 , 0x04970 ,
0x06566 , 0x0d4a0 , 0x0ea50 , 0x06e95 , 0x05ad0 , 0x02b60 , 0x186e3 , 0x092e0 , 0x1c8d7 , 0x0c950 ,
0x0d4a0 , 0x1d8a6 , 0x0b550 , 0x056a0 , 0x1a5b4 , 0x025d0 , 0x092d0 , 0x0d2b2 , 0x0a950 , 0x0b557 ,
0x06ca0 , 0x0b550 , 0x15355 , 0x04da0 , 0x0a5d0 , 0x14573 , 0x052d0 , 0x0a9a8 , 0x0e950 , 0x06aa0 ,
0x0aea6 , 0x0ab50 , 0x04b60 , 0x0aae4 , 0x0a570 , 0x05260 , 0x0f263 , 0x0d950 , 0x05b57 , 0x056a0 ,
0x096d0 , 0x04dd5 , 0x04ad0 , 0x0a4d0 , 0x0d4d4 , 0x0d250 , 0x0d558 , 0x0b540 , 0x0b5a0 , 0x195a6 ,
0x095b0 , 0x049b0 , 0x0a974 , 0x0a4b0 , 0x0b27a , 0x06a50 , 0x06d40 , 0x0af46 , 0x0ab60 , 0x09570 ,
0x04af5 , 0x04970 , 0x064b0 , 0x074a3 , 0x0ea50 , 0x06b58 , 0x055c0 , 0x0ab60 , 0x096d5 , 0x092e0 ,
0x0c960 , 0x0d954 , 0x0d4a0 , 0x0da50 , 0x07552 , 0x056a0 , 0x0abb7 , 0x025d0 , 0x092d0 , 0x0cab5 ,
0x0a950 , 0x0b4a0 , 0x0baa4 , 0x0ad50 , 0x055d9 , 0x04ba0 , 0x0a5b0 , 0x15176 , 0x052b0 , 0x0a930 ,
0x07954 , 0x06aa0 , 0x0ad50 , 0x05b52 , 0x04b60 , 0x0a6e6 , 0x0a4e0 , 0x0d260 , 0x0ea65 , 0x0d530 ,
0x05aa0 , 0x076a3 , 0x096d0 , 0x04bd7 , 0x04ad0 , 0x0a4d0 , 0x1d0b6 , 0x0d250 , 0x0d520 , 0x0dd45 ,
0x0b5a0 , 0x056d0 , 0x055b2 , 0x049b0 , 0x0a577 , 0x0a4b0 , 0x0aa50 , 0x1b255 , 0x06d20 , 0x0ada0
);
var Animals = new Array( " " , " " , " " , " " , " " , " " , " " , " " , " " , " " , " " , " " );
var Gan = new Array( " " , " " , " " , " " , " " , " " , " " , " " , " " , " " );
var Zhi = new Array( " " , " " , " " , " " , " " , " " , " " , " " , " " , " " , " " , " " );
var now = new Date();
var SY = now.getYear();
var SM = now.getMonth();
var SD = now.getDate();

function cyclical(num) { return (Gan[num % 10 ] + Zhi[num % 12 ]) } // ==== 传入 offset 传回干支, 0=甲子
//
==== 传回农历 y年的总天数
function lYearDays(y) {
var i, sum = 348
for (i = 0x8000 ; i & gt; 0x8 ; i & gt; & gt; = 1 ) sum += (lunarInfo[y - 1900 ] & amp; i) ? 1 : 0
return (sum + leapDays(y))
}

// ==== 传回农历 y年闰月的天数
function leapDays(y) {
if (leapMonth(y)) return ((lunarInfo[y - 1900 ] & amp; 0x10000 ) ? 30 : 29 )
else return ( 0 )
}

// ==== 传回农历 y年闰哪个月 1-12 , 没闰传回 0
function leapMonth(y) { return (lunarInfo[y - 1900 ] & amp; 0xf )}

// ====================================== 传回农历 y年m月的总天数
function monthDays(y,m) { return ( (lunarInfo[y - 1900 ] & amp; ( 0x10000 & gt; & gt;m)) ? 30 : 29 )}

// ==== 算出农历, 传入日期物件, 传回农历日期物件
//
该物件属性有 .year .month .day .isLeap .yearCyl .dayCyl .monCyl
function Lunar(objDate) {
var i, leap = 0 , temp = 0
var baseDate = new Date( 1900 , 0 , 31 )
var offset = (objDate - baseDate) / 86400000 / * 这句不懂 */

this .dayCyl = offset + 40
this .monCyl = 14

for (i = 1900 ; i & lt; 2050 & amp; & amp; offset & gt; 0 ; i ++ ) {
temp
= lYearDays(i)
offset
-= temp
this .monCyl += 12
}
if (offset & lt; 0 ) {
offset
+= temp;
i
-- ;
this .monCyl -= 12
}

this .year = i
this .yearCyl = i - 1864

leap
= leapMonth(i) // 闰哪个月
this .isLeap = false

for (i = 1 ; i & lt; 13 & amp; & amp; offset & gt; 0 ; i ++ ) {
// 闰月
if (leap & gt; 0 & amp; & amp; i == (leap + 1 ) & amp; & amp; this .isLeap == false )
{
-- i; this .isLeap = true ; temp = leapDays( this .year); }
else
{ temp
= monthDays( this .year, i); }

// 解除闰月
if ( this .isLeap == true & amp; & amp; i == (leap + 1 )) this .isLeap = false

offset
-= temp
if ( this .isLeap == false ) this .monCyl ++
}

if (offset == 0 & amp; & amp; leap & gt; 0 & amp; & amp; i == leap + 1 )
if ( this .isLeap)
{
this .isLeap = false ; }
else
{
this .isLeap = true ; -- i; -- this .monCyl;}

if (offset & lt; 0 ){ offset += temp; -- i; -- this .monCyl; }

this .month = i
this .day = offset + 1
}

function YYMMDD(){
var cl = ' <font color="green" STYLE="font-size:13pt;"> ' ;
if (now.getDay() == 0 ) cl = ' <font color="#c00000" STYLE="font-size:13pt;"> ' ;
if (now.getDay() == 6 ) cl = ' <font color="green" STYLE="font-size:13pt;"> ' ;
return (cl + SY + ' ' + (SM + 1 ) + ' ' + ' </font> ' );
}
function weekday(){
var day = new Array( " 星期日 " , " 星期一 " , " 星期二 " , " 星期三 " , " 星期四 " , " 星期五 " , " 星期六 " );
var cl = ' <font color="green" STYLE="font-size:9pt;"> ' ;
if (now.getDay() == 0 ) cl = ' <font color="green" STYLE="font-size:9pt;"> ' ;
if (now.getDay() == 6 ) cl = ' <font color="red" STYLE="font-size:9pt;"> ' ;
return (cl + day[now.getDay()] + ' </font> ' );
}
// ==== 中文日期
function cDay(m,d){
var nStr1 = new Array( ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' );
var nStr2 = new Array( ' ' , ' ' , ' 廿 ' , ' ' , '   ' );
var s;
if (m & gt; 10 ){s = ' ' + nStr1[m - 10 ]} else {s = nStr1[m]} s += ' '
switch (d) {
case 10 :s += ' 初十 ' ; break ;
case 20 :s += ' 二十 ' ; break ;
case 30 :s += ' 三十 ' ; break ;
default :s += nStr2[Math.floor(d / 10)]; s += nStr1[d%10];
}
return (s);
}
function solarDay1(){ /* 计算阳历转换成阴历的干支月份和日期 */
var sDObj = new Date(SY,SM,SD);
var lDObj = new Lunar(sDObj);
var cl = ' <font color="#9933CC" STYLE="font-size:9pt;"> ' ;
/* Edit by 郭垠 2011-01-17这一部分是在原来的基础上添加了判断。基本的原则就是阳历跟阴历的天数相差不超过一个月,最大值和最小值相差31天,因此阳历和阴历各自浮动2个月,来判断正确的年份 */
var Y_CN;
if (SM & lt; = 2 & amp; & amp; lDObj.month & gt; = 11 ) {
Y_CN
= Animals[(SY - 4 ) % 12 - 1 ];
}
else {
Y_CN
= Animals[(SY - 4 ) % 12 ];
}
var tt = ' ' + Y_CN + ' ' + cyclical(lDObj.monCyl) + ' ' + cyclical(lDObj.dayCyl ++ ) + ' ' ;
/* Edit end */
return (cl + tt + ' </font> ' );
}
function solarDay2() { /* 计算阳历转换成阴历的月份和日期 */
var sDObj = new Date(SY,SM,SD);
var lDObj = new Lunar(sDObj);
var cl = ' <font color="green" STYLE="font-size:9pt;"> ' ;
// 农历BB'+(cld[d].isLeap?'闰 ':' ')+cld[d].lMonth+' 月 '+cld[d].lDay+' 日
/* Edit by 郭垠 2011-01-17这一部分是在原来的基础上添加了判断。基本的原则就是阳历跟阴历的天数相差不超过一个月,最大值和最小值相差31天,因此阳历和阴历各自浮动2个月,来判断正确的年份 */
var Y_CN_Animal;
if (SM & lt; = 2 & amp; & amp; lDObj.month & gt; = 11 ) {
Y_CN_Animal
= cyclical(SY - 1900 + 36 - 1 );
}
else {
Y_CN_Animal
= cyclical(SY - 1900 + 36 );
}
/* Edit end */
var tt = Y_CN_Animal + ' ' + cDay(lDObj.month, lDObj.day);
return (cl + tt + ' </font> ' );
}
function solarDay3(){
var sTermInfo = new Array( 0 , 21208 , 42467 , 63836 , 85337 , 107014 , 128867 , 150921 , 173149 , 195551 , 218072 , 240693 , 263343 , 285989 , 308563 , 331033 , 353350 , 375494 , 397447 , 419210 , 440795 , 462224 , 483532 , 504758 )
var solarTerm = new Array( " 小寒 " , " 大寒 " , " 立春 " , " 雨水 " , " 惊蛰 " , " 春分 " , " 清明 " , " 谷雨 " , " 立夏 " , " 小满 " , " 芒种 " , " 夏至 " , " 小暑 " , " 大暑 " , " 立秋 " , " 处暑 " , " 白露 " , " 秋分 " , " 寒露 " , " 霜降 " , " 立冬 " , " 小雪 " , " 大雪 " , " 冬至 " )
var lFtv = new Array( " 0101*春节 " , " 0115 元宵节 " , " 0505 端午节 " , " 0707 七夕情人节 " , " 0715 中元节 " , " 0815 中秋节 " , " 0909 重阳节 " , " 1208 腊八节 " , " 1224 小年 " , " 1230*除夕 " )
var sFtv = new Array( " 0101*元旦 " , " 0214 情人节 " , " 0308 妇女节 " , " 0309 偶今天又长一岁拉 " , " 0312 植树节 " , " 0315 消费者权益日 " , " 0401 愚人节 " , " 0418 MM的生日 " , " 0501 劳动节 " , " 0504 青年节 " , " 0512 护士节 " , " 0601 儿童节 " , " 0701 建党节 香港回归纪念 " , " 0801 建军节 " , " 0808 父亲节 " , " 0909 毛席逝世纪念 " , " 0910 教师节 " , " 0928 孔子诞辰 " , " 1001*国庆节 " ,
" 1006 老人节 " , " 1024 联合国日 " , " 1112 孙中山诞辰 " , " 1220 澳门回归纪念 " , " 1225 圣诞节 " , " 1226 毛席诞辰 " )

var sDObj = new Date(SY,SM,SD);
var lDObj = new Lunar(sDObj);
var lDPOS = new Array( 3 )
var festival = '' ,solarTerms = '' ,solarFestival = '' ,lunarFestival = '' ,tmp1,tmp2;
// 农历节日
for (i in lFtv)
if (lFtv[i].match( / ^(\d{2})(.{2})([\s\*])(.+)$ / )) {
tmp1
= Number(RegExp.$ 1 ) - lDObj.month
tmp2
= Number(RegExp.$ 2 ) - lDObj.day
if (tmp1 == 0 & amp; & amp; tmp2 == 0 ) lunarFestival = RegExp.$ 4 ;
}
// 国历节日
for (i in sFtv)
if (sFtv[i].match( / ^(\d{2})(\d{2})([\s\*])(.+)$ / )){
tmp1
= Number(RegExp.$ 1 ) - (SM + 1 )
tmp2
= Number(RegExp.$ 2 ) - SD
if (tmp1 == 0 & amp; & amp; tmp2 == 0 ) solarFestival = RegExp.$ 4
}
// 节气
tmp1 = new Date(( 31556925974.7 * (SY - 1900 ) + sTermInfo[SM * 2 + 1 ] * 60000 ) + Date.UTC( 1900 , 0 , 6 , 2 , 5 ))
tmp2
= tmp1.getUTCDate()
if (tmp2 == SD) solarTerms = solarTerm[SM * 2 + 1 ]
tmp1
= new Date(( 31556925974.7 * (SY - 1900 ) + sTermInfo[SM * 2 ] * 60000 ) + Date.UTC( 1900 , 0 , 6 , 2 , 5 ))
tmp2
= tmp1.getUTCDate()
if (tmp2 == SD) solarTerms = solarTerm[SM * 2 ]

if (solarTerms == '' & amp; & amp; solarFestival == '' & amp; & amp; lunarFestival == '' )
festival
= '' ;
else
festival
= ' <TABLE WIDTH=100% BORDER=0 CELLPADDING=2 CELLSPACING=0 BGCOLOR="#CCFFCC"><TR><TD align=center><marquee direction=left scrolldelay=120 behavior=alternate> ' +
' <FONT COLOR="#FF33FF" STYLE="font-size:9pt;"><b> ' + solarTerms + ' ' + solarFestival + ' ' + lunarFestival + ' </b></FONT></marquee></TD> ' +
' </TR></TABLE> ' ;

var cl = ' <font color="green" STYLE="font-size:9pt;"> ' ;
return (cl + festival + ' </font> ' );
}

// 显示当前时间
function CurentTime()
{
var now = new Date();
var hh = now.getHours();
var mm = now.getMinutes();
var ss = now.getTime() % 60000 ;
ss
= (ss - (ss % 1000 )) / 1000 ;
var clock = hh + ' : ' ;
if (mm & lt; 10 ) clock += ' 0 ' ;
clock
+= mm + ' : ' ;
if (ss & lt; 10 ) clock += ' 0 ' ;
clock
+= ss;
return (clock);
}

function refreshCalendarClock() //
{
document.all.ClockTime.innerHTML
= CurentTime();
}
// 显示当前时间

function setCalendar(){
document.write(
" <table border='1' cellspacing='3' width='180' bordercolor='#009B00' bgcolor='#FFFFFF' height='110' cellpadding='2' " );
document.write(
" <tr><td align='center'><b> " + YYMMDD() + " <br><font face='Arial' size='6' color=#FF8040> " + SD + " </font><br> " );
document.write(weekday()
+ " <br><font id=ClockTime color=red></font> " + " <br></b> " );
document.write(solarDay1()
+ " <br> " + solarDay2() + " <br> " + solarDay3() + " </td></tr></table> " );

}
setCalendar();
setInterval(
' refreshCalendarClock() ' , 1000 ); // 1秒钟刷新1次当前时间
  //--> 
以下是预览的效果。

转载于:https://www.cnblogs.com/TriangleFunction/archive/2011/01/17/1937655.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值