Lua 公历转农历算法

国际通用的历法是以一个太阳回归年为周期,谓之太阳历,简称为阳历,全球公用,故亦称为公历。阳历即是公历。

中国传统的历法自夏朝始,称为夏历,是以月球绕地球一周为一月,十二月为一年,月亮号为太阴,故谓之太阴历,简称为阴历。

 夏历将太阴历配合了闰年及二十四节气,使得太阴历的年周期同步于太阳历。中国夏历其实是阴阳合历。

中国以农业立国,夏历的节气时令等与农业生产密切相关,民国建立后,通用阳历,而将传统的夏历称为农历。一般意义上讲,阴历即是农历。

在lua编程中需要用到公历转换为农历的算法,这里根据c++的算法翻译了一个,发布出来,提供给有需要的Luaer使用

该算法以1921年正月初一作为初始时间开始计算,所以早于该天的计算就不准了

算法很简单,简单修改一下可以提高运行效率,这里我比较懒,就不改了。

 

------------农历转换函数-----------
---by moodlxs(moodlxs@163.com) 2013-1-21
function GetDayOf(st) --天干名称 local cTianGan = {"","","","","","","","","",""} --地支名称 local cDiZhi = {"","","","","","","", "","","","",""} --属相名称 local cShuXiang = {"","","","","","", "","","","","",""} --农历日期名 local cDayName = { "*","初一","初二","初三","初四","初五", "初六","初七","初八","初九","初十", "十一","十二","十三","十四","十五", "十六","十七","十八","十九","二十", "廿一","廿二","廿三","廿四","廿五", "廿六","廿七","廿八","廿九","三十" } --农历月份名 local cMonName = {"*","","","","","","", "","","","","十一",""} --公历每月前面的天数 local wMonthAdd = {0,31,59,90,120,151,181,212,243,273,304,334} -- 农历数据 local wNongliData = {2635,333387,1701,1748,267701,694,2391,133423,1175,396438 ,3402,3749,331177,1453,694,201326,2350,465197,3221,3402 ,400202,2901,1386,267611,605,2349,137515,2709,464533,1738 ,2901,330421,1242,2651,199255,1323,529706,3733,1706,398762 ,2741,1206,267438,2647,1318,204070,3477,461653,1386,2413 ,330077,1197,2637,268877,3365,531109,2900,2922,398042,2395 ,1179,267415,2635,661067,1701,1748,398772,2742,2391,330031 ,1175,1611,200010,3749,527717,1452,2742,332397,2350,3222 ,268949,3402,3493,133973,1386,464219,605,2349,334123,2709 ,2890,267946,2773,592565,1210,2651,395863,1323,2707,265877} local wCurYear,wCurMonth,wCurDay; local nTheDate,nIsEnd,m,k,n,i,nBit; local szNongli, szNongliDay,szShuXiang; ---取当前公历年、月、日--- wCurYear = st.year; wCurMonth = st.mon; wCurDay = st.day; ---计算到初始时间1921年2月8日的天数:1921-2-8(正月初一)--- nTheDate = (wCurYear - 1921) * 365 + (wCurYear - 1921) / 4 + wCurDay + wMonthAdd[wCurMonth] - 38 if (((wCurYear % 4) == 0) and (wCurMonth > 2)) then nTheDate = nTheDate + 1 end --计算农历天干、地支、月、日--- nIsEnd = 0; m = 0; while nIsEnd ~= 1 do if wNongliData[m+1] < 4095 then k = 11; else k = 12; end n = k; while n>=0 do --获取wNongliData(m)的第n个二进制位的值 nBit = wNongliData[m+1]; for i=1,n do nBit = math.floor(nBit/2); end nBit = nBit % 2; if nTheDate <= (29 + nBit) then nIsEnd = 1; break; end nTheDate = nTheDate - 29 - nBit; n = n - 1; end if nIsEnd ~= 0 then break; end m = m + 1; end wCurYear = 1921 + m; wCurMonth = k - n + 1; wCurDay = nTheDate; if k == 12 then if wCurMonth == wNongliData[m+1] / 65536 + 1 then wCurMonth = 1 - wCurMonth; elseif wCurMonth > wNongliData[m+1] / 65536 + 1 then wCurMonth = wCurMonth - 1; end end print('农历', wCurYear, wCurMonth, wCurDay) --生成农历天干、地支、属相 ==> wNongli-- szShuXiang = cShuXiang[(((wCurYear - 4) % 60) % 12) + 1] szShuXiang = cShuXiang[(((wCurYear - 4) % 60) % 12) + 1]; szNongli = szShuXiang .. '(' .. cTianGan[(((wCurYear - 4) % 60) % 10)+1] .. cDiZhi[(((wCurYear - 4) % 60) % 12) + 1] .. ')年' --szNongli,"%s(%s%s)年",szShuXiang,cTianGan[((wCurYear - 4) % 60) % 10],cDiZhi[((wCurYear - 4) % 60) % 12]); --生成农历月、日 ==> wNongliDay--*/ if wCurMonth < 1 then szNongliDay = "" .. cMonName[(-1 * wCurMonth) + 1] else szNongliDay = cMonName[wCurMonth+1] end szNongliDay = szNongliDay .. "" .. cDayName[wCurDay+1] return szNongli .. szNongliDay end function main() local st = {} st.year = 2013 st.mon = 1 st.day = 21 print("" .. GetDayOf(st)) end main()

 

posted @ 2013-01-21 16:43  绿色冰点  Views(5832)  Comments(7Edit  收藏  举报