日期:2014-05-16  浏览次数:20455 次

js公农历转换
看看我的主页,我的网页上除了显示公历之外,还可以显示农历:辛巳年(蛇)五月初十申时,比一般网站上简单的公历显示酷多了!

这究竟是怎么做的呢?耐心看我的文章吧!我们先看看最关键的公历农历转换算法,明白了原理以后就可以“举一反三”了。首先要保存公历农历之间的转换信息: 以任意一年作为起点,把从这一年起若干年(若干是多少?就看你的需要了)的农历信息保存起来(在我的JavaScript脚本中,是以2001年作为起点)。回想一下,我们平常是怎样来转换公历农历的呢?是查万年历,万年历有每一天的公历农历,直接一查就可以了。那么我们可不可以也这样做呢?当然可以,但是,这样做就要收录每一天的信息,工作量就会很大,所以我们要简化这些信息。怎么简化呢?要保存一年的信息,其实只要两个信息就可以了:1.农历每个月的大小;2.今年是否有闰月,闰几月以及闰月的大小。用一个整数来保存这些信息就足够了。具体的方法是:用一位来表示一个月的大小,大月记为1,小月记为0,这样就用掉12 位(无闰月)或13 位(有闰月),再用高4位来表示闰月的月份,没有闰月记为0。比如说,2 0 0 0 年的信息数据是0 x C 9 6 ,化成二进制就是110010010110B,表示的含义是指1、2、5、8、10、11月大,其余月小。2001 年的农历信息数据是0x41A95,其中4表示今年闰4月,月份大小信息就是0x1A95(因为闰月,所以有13 位),具体的就是1、2、4、5、8、10、12月大,其余月份小(0x1A95=1101010010101B),4月的后面那一个0表示的是闰4月小,接着的那个1表示5月大。这样就可以用一个数组来保存这些信息。在我的JavaScript脚本程序中是用CalendarData[]这个数组来保存这些信息的。下面就是公历转换成农历的具体算法:1.计算出所求时间到起始年正月初一的天数。2.从起始年份开始,减去每一月的天数,一直到剩余天数没有下一个月多为止。此时,CalendarData[]的下标到了多少,就是减去了多少年,用起始年份加上这个下标就可以得到农历年份,然后看减去了几个月。如果本年不闰月或者闰月还在后面,就可以直接得到农历月份,如果在闰月月份数后面一个月,则这个月就是闰月,如果在闰月的后面,则要减去1 才能得到月份数。剩余的天数就是农历日,农历时用(公历时+1)/2 就可以简单地得到了。


具体的date.js 代码如下:
var CalendarData=new Array(20);
var madd=new Array(12);
var TheDate=new Date();
var tgString="甲乙丙丁戊己庚辛壬癸";
var dzString="子丑寅卯辰巳午未申酉戌亥";
var numString="一二三四五六七八九十";
var monString="正二三四五六七八九十冬腊";
var weekString="日一二三四五六";
var sx="鼠牛虎兔龙蛇马羊猴鸡狗猪";
var cYear;
var cMonth;
var cDay;
var cHour;
var cDateString;
var DateString;
var Browser=navigator.appName;
function init()
{
CalendarData[0]=0x41A95;
CalendarData[1]=0xD4A;
CalendarData[2]=0xDA5;
CalendarData[3]=0x20B55;
CalendarData[4]=0x56A;
CalendarData[5]=0x7155B;
CalendarData[6]=0x25D;
CalendarData[7]=0x92D;
CalendarData[8]=0x5192B;
CalendarData[9]=0xA95;
CalendarData[10]=0xB4A;
CalendarData[11]=0x416AA;
CalendarData[12]=0xAD5;
CalendarData[13]=0x90AB5;
CalendarData[14]=0x4BA;
CalendarData[15]=0xA5B;
CalendarData[16]=0x60A57;
CalendarData[17]=0x52B;
CalendarData[18]=0xA93;
CalendarData[19]=0x40E95;
madd[0]=0;
madd[1]=31;
madd[2]=59;
madd[3]=90;
madd[4]=120;
madd[5]=151;
madd[6]=181;
madd[7]=212;
madd[8]=243;
madd[9]=273;
madd[10]=304;
madd[11]=334;
}
function GetBit(m,n)
{
return (m>>n)&1;
}
function e2c()
{
var total,m,n,k;
var isEnd=false;
var tmp=TheDate.getYear();
if (tmp<1900) tmp+=1900;
total=(tmp-2001)*365
+Math.floor((tmp-2001)/4)
+madd[TheDate.getMonth()]
+TheDate.getDate()
-23;
if (TheDate.getYear()%4==0&&TheDate.
getMonth()>1)
total++;
for(m=0;;m++)
{
k=(CalendarData[m]<0xfff)?11:12;
for(n=k;n>=0;n--)
{
if(total<=29+GetBit(CalendarData[m],
n))
{
isEnd=true;
break;
}
total=total-29-GetBit(CalendarData
[m],n);
}
if(isEnd)break;
}
cYear=2001 + m;
cMonth=k-n+1;
cDay=total;
if(k==12)
{
if(cMonth==Math.floor(CalendarData
[m]/0x10000)+1)
cMonth=1-cMonth;
if(cMonth>Math.floor(CalendarData[m]/
0x10000)+1)
cMonth--;
}
cHour=Math.floor((TheDate.getHours()
+3)/2);
}
function GetcDateString()
{ var tmp="";
tmp+=tgString.charAt((cYear-4)%10); /
/年干
tmp+=dzString.charAt((cYear-4)%12); /
/年支
tmp+="年(";
tmp+=sx.charAt((cYear-4)%12);
tmp+=")";
if(cMonth<1)
{
tmp+="闰";
tmp+=monString.charAt(-cMonth-1);
}
else
tmp+=monString.charAt(cMonth-1);
tmp+="月";
tmp+=(cDay<11)?"初":((cDay<20)?"十":
((cDay<30)?"廿":"卅"));
if(cDay%10!=0||cDay==10)
tmp+=numString.charAt((cDay-1)%10);
if(cHour==13)tmp+="夜";
tmp+=dzString.charAt((cHour-1)%12);
tmp+="时";
cDateString=tmp;
return tmp;
}
fun