加载中…
正文 字体大小:

[转载]将阳历(公历)转阴历(农历)的算法

(2011-12-06 17:10:48)
标签:

转载

分类: 技术学习
原来农历还包含这么多东西

1 关于农历的知识(ZT) 

 阳历、阴历、农历 

 阳历(即公历),是世界上多数国家通用的历法,由"儒略历"修订而成。儒略历是公元前46年,古罗马统帅儒略、恺撒决定采用的历法。

阳历,是以地球绕太阳运动作为根据的历法。它以地球绕太阳一周(一回归年)为一年。一回归年的长度是365.2422日,也就是3655小时4846秒,积累4年共有23小时154秒,大约等于一天,所以每4年增加1天,加在2月的末尾,得366天,就是闰年。但是4年加1天实际回归年多了4456秒,积满128年左右就又多算了一天,也就是在400年中约多算了3天。

阳历闰年规定:公元年数可用4整除的,就算闰年;为了要在400年减去多算的3天,并规定公元世纪的整数,即公元年数是100的整数时,须用400来整除的才算闰年,如1600年、2000年、2200年、2400年就是闰年。这样就巧妙地在400年中减去了3天,阳历规定每年都是12个月,月份的大小完全是人为的规定,现在规定每年的135781012月为大月,每月31天;46911月为小月,每月30天;2月平年是28天,闰年是29天。

阴历,是根据月相圆缺变化的周期(即朔望月)来制订的。因为古人称月亮为太阴,所以又有太阴历之称,是纯粹的阴历,我国使用"农历",一般人叫它"阴历",那是不对的。农历不是一种纯粹的阴历,而是"阴阳历"

阴历把月亮圆缺循环一次的时间算做一个月,12个月算做一年。然而月亮圆缺循环一次--一个朔望月,是2912443秒,比29天多,又比30天少。为方便,阴历把月份分成大月和小月两种,逢单的月是大月30天,逢双的月是小月29天,一年共是354天。

实际上,一个朔望月并不正好等于一个大月和一个小月的平均数--29天半,而是比29天半多442.8秒。所以12个朔望月实际上要比354天多8小时4834秒,30年就要多出11天。因此,阴历30年中就要安插11年闰年,每逢闰年就在12个月多加一天。阴历的闰年是355天。这样,阴历每30年中有19354天,11355天,平均一年的长度是3548小时48分。它的一年比回归年差不多短了11天。3年就短一个多月,17年就要短6个多月了。所以使用这种历时,新年不一定在冬天过,它可以在春天过,也可以在夏天或秋天过。它的惟一好处就是阴历上的每一个日期都可以知道月亮的形状。

阴历作为一种历法,由于它与农业生产和人们的日常生活不相协调,所以当今世界上除了几个伊斯兰教国家因为宗教上的原因仍然使用外,其他国家一般已经废弃不用了。

农历,是把朔望月的时间作为历月的平均时间。这一点上和纯粹的阴历相同,但农历运用了设置闰月的办法和二十四节气的办法,使历年的平均长度等于回归年,这样它就又具有了阳历的成分,所以它比纯粹的阴历好。

现在所有的农历,据说我们的祖先远在夏代(公元前17世纪以前)就使用了这种历法。所以人们又称它为夏历。解放后还仍然叫做夏历,1970年以后我国改称为"农历"。至于"农历"一名的由来,大概因为由于自古以农立国,所以制订历法必须为农业服务。

农历的历月是以朔望月为依据的。朔望月的时间是2912小时443秒(即29.5366日),因此农历也是大月30天,小月29天,但它和纯粹的阴历并不完全一样,因为纯粹的阴历是大小月交替编排的,而农历年大小月是经过推算决定的。

农历每一个月初一都正好是""(即月亮在太阳地球中间,且以黑着的半面对着地球的时候)。有时可能出现两个大月,也可以连续出现两个小月。由于朔望月稍大于29天半,所以在农历的每100个历月里约有53个大月和47个小月。

农历是基本上以12个月作为一年的,但12个朔望月的时间是354.3667日,和回归年比起来要相差11天左右。这样每隔3年就要多出33天,即多出一个多月。

为了要把多余的日数消除,每隔3年就要加一个月,这就是农历的闰月。有闰月的一年也叫闰年。所以农历的闰年就有13个月了。至于闰哪个月是由节气情况决定的。

 

 

 

【二十四节气】

 

 

 

 作者: 202.116.24.*  2005-1-22 21:33   回复此发言   

 

--------------------------------------------------------------------------------

 

2 关于农历的知识(ZT) 

 

  我国农历里把节气分得很细,定出了二十四节气,它们的名称大都反应物候、农时或季节的起点与中点。由于节气实际反应太阳运行所引起的气候变化,故二十四节气为阳历的自然衍生的产物,与阴历无关。

 

  二十四节气中以立春、春分、立夏,夏至、立秋、秋分、立冬与冬至等八节气最为重要。它们之间大约相隔46天。一年分为四季,「立」表示四季中每一个季节的开始,而「分」与「至」表示正处于这季节的中间。

 

  现代我国所使用的历法,皆依回归年制定,二十四节气基本上是一致的,前后的相差不会超过一两天。为了调合回归年(阳历)与朔望月(阴历)之间的差异,农历把二十四节气中,双数的叫中气,单数的叫节气,而且规定每一个中气标定在一个农历的月份,例如雨水必定在正月,春分必定在二月,谷雨必定在三月,其余依此类推。另外,月名也必须和相对应的中气相合。

 

 

  立春 立是开始的意思,春是蠢动,表示万物开始有生气,这一天春天开始。

  雨水 降雨开始,雨水将多。

 

  惊蛰 春雷响动,惊动蛰伏地下冬眠的生物,它们将开始出土活动。

  春分 这是春季九十天的中分点,这一天昼夜相等,所以古代曾称春分秋分为昼夜分。

 

  清明 明洁晴朗,气候温暖,草木开始萌发繁茂。

  谷雨 雨生百谷的意思。雨水增多,适时的降雨对谷物生长很为有利。

 

  立夏 夏天开始,万物渐将随温暖的气候而生长。

  小满 满指籽粒饱满,麦类等夏热作物这时开始结籽灌浆,即将饱满。

 

  芒种 有芒作物开始成熟,此时也是秋季作物播种的最繁忙时节。

  夏至 白天最长,黑夜最短,这一天中午太阳位置最高,日影短至终极,古代又称这一天为日北至或长日至。

 

  小暑 暑是炎热,此时还未到达最热。

  大暑 炎热的程度到达高峰。

 

  立秋 秋天开始,植物快成熟了。

  处暑 处是住的意思,表示暑气到此为止。

 

  白露 地面水气凝结为露,色白,是天气开始转凉了。

  秋分 秋季九十天的中间,这一天昼夜相等,同春分一样,太阳从正东升起正西落下。

 

  寒露 水露先白而后寒,是气候将逐渐转冷的意思。

  霜降 水气开始凝结成霜。

 

  立冬 冬是终了,作物收割后要收藏起来的意思,这一天起冬天开始。

  小雪 开始降雪,但还不多。

 

  大雪 雪量由小增大。

  冬至 这一天中午太阳在天空中位置最低,日影最长,白天最短,黑夜最长,古代又称短日至或日南至。

 

  小寒 冷气积久而为寒,此时尚未冷到顶点。

  大寒 天候达到最寒冷的程度 

 

 

 

 

 

农历为何要设置闰月? 

 

  目前我们所用的阳历,是以地球围绕太阳公转一圈为一回归年而制定的,回归年长度是365.2422天。阴历是以月亮的圆缺变化而制定的,一个朔望月的长度是29.53天。农历是以阴历为基础,它的日期既能显示月亮的盈亏变化,又能与公历的四季保持同步。 

 

  广东天文学会的专家说,农历一年按12个朔望月计算,只有354.4天,比阳历回归年少10.9天。如果今年不安插闰二月,那么,明年春节就会出现在 2005110日。再过几年,农历就会出现“六月飞雪”的现象。为了协调阴历与阳历的季节关系,我国在春秋时代就采用“十九年七闰月”,即在19个回归年(6939.6天)中,农历要安插七个闰月。19个农历年有228个朔望月,再加上七个闰月,就有235个朔望月(6939.7天)。因此,农历19年安插七个闰月,就能使农历的寒暑变化与公历基本一致。 

 

  闰月怎样安插最恰当? 

 

  闰月怎样安插才最恰当呢?这要从24个节气谈起。24个节气,我国在汉朝就有了。它从立春开始,到大寒结束。从立春数起,逢单数的称为节气,逢双数的称为中气。农历月份是以中气作为标志的。一年中,以春分、夏至、秋分和冬至这四个中气为最重要。我国从1645年起就在没有中气的月份安插闰月,这是合情合理的。因为19个回归年中共有228个中气和235个朔望月,朔望月比中气多七个。因此,有七个朔望月没有中气就自然而然地成为闰月。今年农历闰二月,就只有“清明”一个节气,而没有中气。

 

 

 [C#]代码

001 /// <summary>
002     /// LunDay 的摘要说明。
003     /// 用法说明
004     /// 直接调用即可,比较简单
005     /// </summary>
006     public class LunDay
007     {
008         public LunDay()
009         {
010             //
011             // TODO: 在此处添加构造函数逻辑
012             //
013         }
014         //天干
015         private static string[] TianGan = { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" };
016   
017         //地支
018         private static string[] DiZhi = { "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" };
019   
020         //十二生肖
021         private static string[] ShengXiao = { "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" };
022   
023         //农历日期
024         private static string[] DayName =   {"*","初一","初二","初三","初四","初五",
025              "初六","初七","初八","初九","初十",
026              "十一","十二","十三","十四","十五",
027              "十六","十七","十八","十九","二十",
028              "廿一","廿二","廿三","廿四","廿五"     
029              "廿六","廿七","廿八","廿九","三十"};
030   
031         //农历月份
032         private static string[] MonthName = { "*", "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "腊" };
033   
034         //公历月计数天
035         private static int[] MonthAdd = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
036         //农历数据
037         private static int[] LunarData = {2635,333387,1701,1748,267701,694,2391,133423,1175,396438
038             ,3402,3749,331177,1453,694,201326,2350,465197,3221,3402
039             ,400202,2901,1386,267611,605,2349,137515,2709,464533,1738
040             ,2901,330421,1242,2651,199255,1323,529706,3733,1706,398762
041             ,2741,1206,267438,2647,1318,204070,3477,461653,1386,2413
042             ,330077,1197,2637,268877,3365,531109,2900,2922,398042,2395
043             ,1179,267415,2635,661067,1701,1748,398772,2742,2391,330031
044             ,1175,1611,200010,3749,527717,1452,2742,332397,2350,3222
045             ,268949,3402,3493,133973,1386,464219,605,2349,334123,2709
046             ,2890,267946,2773,592565,1210,2651,395863,1323,2707,265877};
047         /// <summary>
048         /// 获取对应日期的农历
049         /// </summary>
050         /// <param name="dtDay">公历日期</param>
051         /// <returns></returns>
052         public string GetLunarCalendar(DateTime dtDay)
053         {
054             string sYear = dtDay.Year.ToString();
055             string sMonth = dtDay.Month.ToString();
056             string sDay = dtDay.Day.ToString();
057             int year;
058             int month;
059             int day;
060             try
061             {
062                 year = int.Parse(sYear);
063                 month = int.Parse(sMonth);
064                 day = int.Parse(sDay);
065             }
066             catch
067             {
068                 year = DateTime.Now.Year;
069                 month = DateTime.Now.Month;
070                 day = DateTime.Now.Day;
071             }
072   
073             int nTheDate;
074             int nIsEnd;
075             int k, m, n, nBit, i;
076             string calendar = string.Empty;
077             //计算到初始时间1921年2月8日的天数:1921-2-8(正月初一)
078             nTheDate = (year - 1921) * 365 + (year - 1921) / 4 + day + MonthAdd[month - 1] - 38;
079             if ((year % 4 == 0) && (month > 2))
080                 nTheDate += 1;
081             //计算天干,地支,月,日
082             nIsEnd = 0;
083             m = 0;
084             k = 0;
085             n = 0;
086             while (nIsEnd != 1)
087             {
088                 if (LunarData[m] < 4095)
089                     k = 11;
090                 else
091                     k = 12;
092                 n = k;
093                 while (n >= 0)
094                 {
095                     //获取LunarData[m]的第n个二进制位的值
096                     nBit = LunarData[m];
097                     for (i = 1; i < n + 1; i++)
098                         nBit = nBit / 2;
099                     nBit = nBit % 2;
100                     if (nTheDate <= (29 + nBit))
101                     {
102                         nIsEnd = 1;
103                         break;
104                     }
105                     nTheDate = nTheDate - 29 - nBit;
106                     n = n - 1;
107                 }
108                 if (nIsEnd == 1)
109                     break;
110                 m = m + 1;
111             }
112             year = 1921 + m;
113             month = k - n + 1;
114             day = nTheDate;
115             //return year+"-"+month+"-"+day;
116   
117             #region 格式化日期显示为三月廿四
118             if (k == 12)
119             {
120                 if (month == LunarData[m] / 65536 + 1)
121                     month = 1 - month;
122                 else if (month > LunarData[m] / 65536 + 1)
123                     month = month - 1;
124             }
125   
126             //生肖
127             calendar = ShengXiao[(year - 4) % 60 % 12].ToString() + "年 ";
128             //天干
129             calendar += TianGan[(year - 4) % 60 % 10].ToString();
130             //地支
131             calendar += DiZhi[(year - 4) % 60 % 12].ToString() + " ";
132   
133             //农历月
134             if (month < 1)
135                 calendar += "闰" + MonthName[-1 * month].ToString() + "月";
136             else
137                 calendar += MonthName[month].ToString() + "月";
138   
139             //农历日
140             calendar += DayName[day].ToString() + "日";
141   
142             return calendar;
143   
144             #endregion
145         }
146     }

 

 

下面是一个关于VB的农历算法

'日期数据定义方法如下

'前12个字节代表1-12月为大月或是小月,1为大月30天,0为小月29天;

'第13位为闰月的情况,1为大月30天,0为小月29天;

'第14位为闰月的月份,如果不是闰月为0,否则给出月份,10、11、12分别用A、B、C来表示,即使用16进制;

'最后4位为当年家农历新年-即农历1月1日所在公历的日期,如0131代表1月31日。

Function GetChgDate(ByVal vDate As String, ByVal ChgType As 转换方式) As String

Dim vvdate() As String = Split(vDate, "-")



If vvdate(0) > 2011 Or vvdate(0) < 1900 Then

Throw New NotSupportedException("本函数只提供1900年至2011年的日历转换!")

End If



Dim AddMonth, AddDay, AddYear, getDay, i As Integer

Dim RunYue As Boolean

Dim conDate As DateTime



Dim daList(2011) As String

daList(1900) = "010010110110180131"

daList(1901) = "010010101110000219"

daList(1902) = "101001010111000208"

daList(1903) = "010100100110150129"

daList(1904) = "110100100110000216"

daList(1905) = "110110010101000204"

daList(1906) = "011010101010140125"

daList(1907) = "010101101010000213"

daList(1908) = "100110101101000202"

daList(1909) = "010010101110120122"

daList(1910) = "010010101110000210"

daList(1911) = "101001001101160130"

daList(1912) = "101001001101000218"

daList(1913) = "110100100101000206"

daList(1914) = "110101010100150126"

daList(1915) = "101101010101000214"

daList(1916) = "010101101010000204"

daList(1917) = "100101101101020123"

daList(1918) = "100101011011000211"

daList(1919) = "010010011011170201"

daList(1920) = "010010011011000220"

daList(1921) = "101001001011000208"

daList(1922) = "101100100101150128"

daList(1923) = "011010100101000216"

daList(1924) = "011011010100000205"

daList(1925) = "101011011010140124"

daList(1926) = "001010110110000213"

daList(1927) = "100101010111000202"

daList(1928) = "010010010111120123"

daList(1929) = "010010010111000210"

daList(1930) = "011001001011060130"

daList(1931) = "110101001010000217"

daList(1932) = "111010100101000206"

daList(1933) = "011011010100150126"

daList(1934) = "010110101101000214"

daList(1935) = "001010110110000204"

daList(1936) = "100100110111030124"

daList(1937) = "100100101110000211"

daList(1938) = "110010010110170131"

daList(1939) = "110010010101000219"

daList(1940) = "110101001010000208"

daList(1941) = "110110100101060127"

daList(1942) = "101101010101000215"

daList(1943) = "010101101010000205"

daList(1944) = "101010101101140125"

daList(1945) = "001001011101000213"

daList(1946) = "100100101101000202"

daList(1947) = "110010010101120122"

daList(1948) = "101010010101000210"

daList(1949) = "101101001010170129"

daList(1950) = "011011001010000217"

daList(1951) = "101101010101000206"

daList(1952) = "010101011010150127"

daList(1953) = "010011011010000214"

daList(1954) = "101001011011000203"

daList(1955) = "010100101011130124"

daList(1956) = "010100101011000212"

daList(1957) = "101010010101080131"

daList(1958) = "111010010101000218"

daList(1959) = "011010101010000208"

daList(1960) = "101011010101060128"

daList(1961) = "101010110101000215"

daList(1962) = "010010110110000205"

daList(1963) = "101001010111040125"

daList(1964) = "101001010111000213"

daList(1965) = "010100100110000202"

daList(1966) = "111010010011030121"

daList(1967) = "110110010101000209"

daList(1968) = "010110101010170130"

daList(1969) = "010101101010000217"

daList(1970) = "100101101101000206"

daList(1971) = "010010101110150127"

daList(1972) = "010010101101000215"

daList(1973) = "101001001101000203"

daList(1974) = "110100100110140123"

daList(1975) = "110100100101000211"

daList(1976) = "110101010010180131"

daList(1977) = "101101010100000218"

daList(1978) = "101101101010000207"

daList(1979) = "100101101101060128"

daList(1980) = "100101011011000216"

daList(1981) = "010010011011000205"

daList(1982) = "101001001011140125"

daList(1983) = "101001001011000213"

daList(1984) = "1011001001011A0202"

daList(1985) = "011010100101000220"

daList(1986) = "011011010100000209"

daList(1987) = "101011011010060129"

daList(1988) = "101010110110000217"

daList(1989) = "100100110111000206"

daList(1990) = "010010010111150127"

daList(1991) = "010010010111000215"

daList(1992) = "011001001011000204"

daList(1993) = "011010100101030123"

daList(1994) = "111010100101000210"

daList(1995) = "011010110010180131"

daList(1996) = "010110101100000219"

daList(1997) = "101010110110000207"

daList(1998) = "100100110110150128"

daList(1999) = "100100101110000216"

daList(2000) = "110010010110000205"

daList(2001) = "110101001010140124"

daList(2002) = "110101001010000212"

daList(2003) = "110110100101000201"

daList(2004) = "010110101010120122"

daList(2005) = "010101101010000209"

daList(2006) = "101010101101170129"

daList(2007) = "001001011101000218"

daList(2008) = "100100101101000207"

daList(2009) = "110010010101150126"

daList(2010) = "101010010101000214"

daList(2011) = "101101001010000214"

AddYear = vvdate(0)



If ChgType = 转换方式.阴历转阳历 Then

AddMonth = Val(Mid(daList(AddYear), 15, 2))

AddDay = Val(Mid(daList(AddYear), 17, 2))

conDate = DateSerial(AddYear, AddMonth, AddDay)

AddDay = vvdate(2)

For i = 1 To vvdate(1) - 1

AddDay = AddDay + 29 + Val(Mid(daList(vvdate(0)), i, 1))

Next i

Return DateAdd(DateInterval.Day, AddDay - 1, conDate)

Else

CHUSHIHUA:

AddMonth = Val(Mid(daList(AddYear), 15, 2))

AddDay = Val(Mid(daList(AddYear), 17, 2))

conDate = DateSerial(AddYear, AddMonth, AddDay)

Dim vtDate As DateTime

Try

vtDate = CType(vDate, DateTime)

Catch ex As Exception

Throw New NotSupportedException("阳历日期输入错误!")

End Try





getDay = DateDiff(DateInterval.Day, conDate, vtDate)

If getDay < 0 Then AddYear = AddYear - 1 : GoTo CHUSHIHUA

AddDay = 1

AddMonth = 1

For i = 1 To getDay

AddDay = AddDay + 1

If AddDay = 30 + Mid(daList(AddYear), AddMonth, 1) Or (RunYue And AddDay = 30 + Mid(daList(AddYear), 13, 1)) Then

If RunYue = False And AddMonth = Val("&H" & Mid(daList(AddYear), 14, 1)) Then

RunYue = True

Else

RunYue = False

AddMonth = AddMonth + 1

End If

AddDay = 1

End If



Next

Return AddYear & "-" & AddMonth & "-" & AddDay

End If



End Function



Enum 转换方式

阴历转阳历 = 1

阳历转阴历 = 0

End Enum

 

 

以下就是公历转换成农历的算法和JavaScript 代码

我们先看看最关键的公历农历转换算法,明白了原理以后就可以“举一反三”了。首先要保存公历农历之间的转换信息: 以任意一年作为起点,把从这一年起若干年(若干是多少?就看你的需要了)的农历信息保存起来(在我的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)); /
/年干
tmp+=dzString.charAt((cYear-4)); /
/年支
tmp+="年(";
tmp+=sx.charAt((cYear-4));
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!=0||cDay==10)
tmp+=numString.charAt((cDay-1));
if(cHour==13)tmp+="夜";
tmp+=dzString.charAt((cHour-1));
tmp+="时";
cDateString=tmp;
return tmp;
}
function GetDateString()
{
var tmp="";
var t1=TheDate.getYear();
if (t1<1900)t1+=1900;
tmp+=t1
+"-"
+(TheDate.getMonth()+1)+"-"
+TheDate.getDate()+" "
+TheDate.getHours()+":"
+((TheDate.getMinutes()<10)?"0":"")
+TheDate.getMinutes()
+" 星期"+weekString.charAt
(TheDate.getDay());
DateString=tmp;
return tmp;
}
init();
e2c();
GetDateString();
GetcDateString();
document.write(DateString,"<br>",cDateString);
你可以这样写一个HTML文件调
用date.js:
<html>
<head>
</head>
<body>
<script language="JavaScript"
src="date.js"></script>
</body>
</html>

以上就是公历转换成农历的算法和JavaScript 代码,只要理解了这些算法,你就不难写出农历到公历的转换程序,也不难写出其他语言的程序。我就写了VCL 和PHP 的代码,其中VCL代码还包括农历到公历的转换,并且还可以转换一百年的日期(1921-2020)。

0

阅读 评论 收藏 转载原文 喜欢 打印举报
  • 评论加载中,请稍候...
发评论

       

    验证码: 请点击后输入验证码 收听验证码

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 不良信息反馈 电话:4006900000 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有