世界各國的日歷都是以天為最小單位,但是關于年和月的算法卻各不相同,大致可以分為三類:
陽歷--以天文年作為日歷的主要周期,例如:中國公歷(格里歷)
陰歷--以天文月作為日歷的主要周期,例如:伊斯蘭歷
陰陽歷--以天文年和天文月作為日歷的主要周期,例如:中國農(nóng)歷
我國古人很早就開始關注天象,定晝夜交替為“日”,月輪盈虧為“月”,寒暑交替為“年”,在總結(jié)日月變化規(guī)律的基礎上制定了兼有陰歷月和陽歷年性質(zhì)的歷法,稱為中國農(nóng)歷。本文將介紹中國農(nóng)歷的歷法規(guī)則、天干地支(Heavenly Stems,Earthly Branches)的計算方法以、二十四節(jié)氣與中國農(nóng)歷的關系以及知道節(jié)氣和日月合朔的精確時間的情況下推算中國農(nóng)歷年歷的方法。
在介紹中國農(nóng)歷的歷法之前,必須要先介紹一下中國古代的紀年方法。中國古代用天干地支紀年,嚴格來講,天干地支紀年以及十二屬相并不是中國農(nóng)歷歷法的一部分,但是在中國歷史上直到今天,天干地支以及十二屬相一直都是做為中國農(nóng)歷紀年關系密切的一部分而存在,因此這里先介紹一下天干地支紀年法以及十二屬相。
中國古代紀年不用數(shù)字,而是采用天干地支組合。天干有十個,分別是:甲、乙、丙、丁、戊、己、庚、辛、壬、癸;地支有十二個,分別是:子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥。使用時天干地支各取一字,天干在前,地支在后,組合成干支,例如甲子、乙丑、丙寅等等,依次輪回可形成六十種組合,以這些天干地支組合紀年,每六十年一個輪回,稱為一個甲子。實際上中國古代紀月、紀日以及紀時辰都采用干支方法,這些干支組合起來就是我們熟悉的生辰八字。十二屬相又稱“十二生肖”,由十一種源自自然界的動物:鼠、牛、虎、兔、蛇、馬、羊、猴、雞、狗、豬以及傳說中的龍組成,用于紀年時,按順序和十二地支組合成子鼠、丑牛、寅虎、卯兔、辰龍、巳蛇、午馬、未羊、申猴、酉雞、戌狗和亥豬。天干地支以及十二生肖常組合起來描述農(nóng)歷年,比如公歷2011年就是農(nóng)歷辛卯兔年、2012年是壬辰龍年等等。
計算某一年的天干地支,有很多經(jīng)驗公式,如果知道某一年的天干地支,也可以直接推算其它年份的天干地支。舉個例子,如果知道2000年是庚辰龍年,則2012年的干支可以這樣推算:(2012-2000)% 10=2,2012年的天干就是從庚開始向后推2個天干,即壬;2012年的地支可以這樣推算:(2012 - 2000)% 12 = 0,2012年的地支仍然是辰,因此2012年的天干地支就是壬辰,十二生肖龍年。對于2000年以前的年份,計算出年份差后只要將天干和地支向前推算即可。例如1995年的干支可以這樣計算:(2000 – 1995)%10 = 5,(2000 – 1995)%12 = 5,庚向前推算5即是乙,辰向前推算5即是亥,因此1995年的干支就是乙亥,十二生肖豬年。這個干支推算算法的實現(xiàn)如下:
202 void CalculateYearGanZhi(int year, int *gan, int *zhi) 203 { 204 int sc = year - 2000; 205 *gan = (7 + sc) % 10; 206 *zhi = (5 + sc) % 12; 207 208 if(*gan < 0) 209 *gan += 10; 210 if(*zhi < 0) 211 *zhi += 12; 212 } |
獲得2008年的干支紀年:
9 TCHAR *nameOfTianGan[COUNTS_FOR_TIANGAN] = { _T("甲"),_T("乙"),_T("丙"),_T("丁"),_T("戊"),_T("己"),_T("庚"),_T("辛"),_T("壬"),_T("癸") }; 10 TCHAR *nameOfDiZhi[COUNTS_FOR_DIZHI] = { _T("子"),_T("丑"),_T("寅"),_T("卯"),_T("辰"),_T("巳"),_T("午"),_T("未"),_T("申"),_T("酉"),_T("戌"),_T("亥") }; 146 int gan,zhi; 147 148 CalculateYearGanZhi(2008, &gan, &zhi); 149 150 text.Format(_T("農(nóng)歷【%s%s】%s年"), 151 year, m_curMonth, nameOfTianGan[gan - 1], nameOfDiZhi[zhi - 1], nameOfShuXiang[zhi - 1]); |
結(jié)果是:農(nóng)歷戊子鼠年。
中國農(nóng)歷是以月亮運行周期為基礎,結(jié)合太陽運行規(guī)律(二十四節(jié)氣)制定的歷法,農(nóng)歷月的定義規(guī)則就是中國農(nóng)歷歷法的關鍵,因此要了解中國農(nóng)歷的歷法規(guī)則,就必須知道如何定義月,如何設置閏月?中國農(nóng)歷的一年有十二個月或十三個月,但是正統(tǒng)的叫法只有十二個月,分別是正月、二月、三月、四月、五月、六月、七月、八月、九月、十月、冬月和臘月(注意,正統(tǒng)的中國農(nóng)歷是沒有十一月和十二月的,如果你用的歷法軟件有顯示農(nóng)歷十一月和農(nóng)歷十二月,就說明非常不專業(yè))。中國民間常用“十冬臘月天”來形容寒冷的天氣,其實指的就是十月,十一月和十二月這三個最冷的月份。一年有十三個月的情況是因為有閏月,多出來的這個閏月沒有月名,只是跟在某個月后面,稱為閏某月。比如公歷2009年對應的農(nóng)歷乙丑年,就是閏五月,于是這一年可以過兩個端午節(jié)。
中國農(nóng)歷為什么會有閏月?其實中國農(nóng)歷置閏月是為了協(xié)調(diào)回歸年和農(nóng)歷年的矛盾。前面提到過,中國農(nóng)歷是一種陰陽歷,農(nóng)歷的月分大月和小月,大月一個月是30天,小月一個月是29天。中國農(nóng)歷把日月合朔(太陽和月亮的黃經(jīng)相同,但是月亮不可見)的日期定位月首,也就是“初一”,把月圓的時候定為望日,也就是“十五”,月亮繞地球公轉(zhuǎn)一周稱為一個朔望月。天文學的朔望月長度是29.5306日,中國農(nóng)歷以朔望月為基礎,嚴格保證每個月的頭一天是朔日,這就使得每個月是大月還是小月的安排不能固定,通常需要通過天文學觀測和計算來確定。一個農(nóng)歷年由12個朔望月組成,這樣一個農(nóng)歷年的長度就是29.5306 12 = 354.3672日,而陽歷的一個天文學回歸年是365.2422日,這樣一個農(nóng)歷年就比一個回歸年少10.88天,這個誤差如果累計起來過16年就會出現(xiàn)“六月飛雪”的奇觀了。為了協(xié)調(diào)農(nóng)歷年和回歸年之間的矛盾,聰明的先人在天文觀測的基礎上,找到了“閏月”的方法,通過在適當?shù)脑路莶迦腴c月來保證每個農(nóng)歷年的正月到三月是春季,四月到六月是夏季,七月到九月是秋季,十月到十二月是冬季,也就是說,讓歷法和天文氣象能夠基本對上,不至于出現(xiàn)“六月飛雪”。
那么多長時間增加一個閏月比較合適呢?最早人們推算是“三年一閏”,后來是“五年兩潤”,隨著歷法計算的精確,最終定型為“十九年七閏”。這個“十九年七閏”又是怎么算出來的呢?其實就是求出回歸年日數(shù)和朔望月日數(shù)的最小公倍數(shù),也就是m個回歸年的天數(shù)和n個朔望月的天數(shù)相等,即:
m 365.2422 = n 29.5306
這樣m和n的比例就是29.5306 : 365.2422 19 : 235,按照這個最接近的整數(shù)倍數(shù)關系,每19個回歸年需要添加的閏月就是:
235 – 12 19 = 7
也就是“十九年七閏”的由來。但是需要注意的是,“十九年七閏”也并不是精確的結(jié)果,每19年就會有0.0892天的誤差:
19 365.2422 - 235 29.5306 0.0892
這樣每213年就會積累約1天的誤差,因此,即使按照“十九年七閏”計算,中國農(nóng)歷每一兩百年就需要修正一次。正因為這樣,現(xiàn)行農(nóng)歷從唐代以后就已經(jīng)不再遵守“十九年七閏”法,而是采用更準確的“中氣置閏”法?!爸袣庵瞄c”法更準確的名稱應該是“定冬至”法,就是定兩個冬至節(jié)氣之間的時間為一個農(nóng)歷年,這樣農(nóng)歷年的長度就和太陽回歸年長度對應,不會產(chǎn)生誤差。
現(xiàn)在,我們知道農(nóng)歷通過置閏月的方式協(xié)調(diào)農(nóng)歷年和回歸年長度不相等的問題,也知道了置閏的方法是“中氣置閏”法,那么到底什么是“中氣”,又是如何定中氣置閏月呢?要回答這個問題,就需要介紹另一個天文現(xiàn)象――節(jié)氣。二十四節(jié)氣起源于黃河流域,遠在春秋時代,就定出仲春、仲夏、仲秋和仲冬等四個節(jié)氣。以后不斷地改進與完善,到秦漢年間,二十四節(jié)氣已完全確立,漢武帝太初元年(公元104年)制定的《太初歷》,則第一次從歷法上明確了二十四節(jié)氣的天文位置。
地球沿著一個近似橢圓軌道繞太陽公轉(zhuǎn),這個公轉(zhuǎn)軌道所在的平面就是“黃道面”,黃道面向外延伸與天球的交線就是“黃道”。古人由于觀測條件限制,只能根據(jù)視覺感覺認為是太陽沿著黃道繞地球運轉(zhuǎn),因此設定太陽從黃經(jīng)(黃道經(jīng)度)零度起(以春分點為起點自西向東度量),將太陽沿黃經(jīng)每運行15度所經(jīng)歷的時日稱為“一個節(jié)氣”。太陽每年運行360度,共經(jīng)歷二十四個節(jié)氣,春季的節(jié)氣有立春(315度)、雨水(330度)、驚蟄(345度)、春分(0度、360度)、清明(15度)和谷雨(30度),夏季的節(jié)氣有立夏(45度)、小滿(60度)、芒種(75度)、夏至(90度)、小暑(105度)和大暑(120度),秋季的節(jié)氣有立秋(135度)、處暑(150度)、白露(165度)、秋分(180度)、寒露(195度)和霜降(210度)。冬季的節(jié)氣有立冬(225度)、小雪(240度)、大雪(255度)、冬至(270度)、小寒(285度)和大寒(300度)。二十四節(jié)氣又細分為十二節(jié)氣和十二中氣,二十四節(jié)氣按照順序排在奇數(shù)位置上的就是節(jié)氣,排在偶數(shù)位置上的就是中氣。也就是說,立春、驚蟄、清明、立夏、芒種、小暑、立秋、白露、寒露、立冬、大雪和小寒就是十二個節(jié)氣,而雨水、春分、谷雨、小滿、夏至、大暑、處暑、秋分、霜降、小雪、冬至和大寒就是十二個中氣。二十四個節(jié)氣平分在公歷的12個月中,每月一節(jié)氣一中氣。二十四節(jié)氣反映了太陽的周年運動(以地球為參照物的視運動),所以節(jié)氣在現(xiàn)行的公歷中日期基本固定,上半年在6日、21日,下半年在8日、23日,前后不差 1~2天。中國民間流傳的《二十四節(jié)氣歌》就是為了方便記憶這些節(jié)氣:
春雨驚春清谷天,
夏滿芒夏暑相連,
秋處露秋寒霜降,
冬雪雪冬小大寒,
每月兩節(jié)不變更,
最多相差一兩天。
傳統(tǒng)上一個農(nóng)歷年起于冬至,終于冬至,因此要確定在哪一年置閏,主要看那一年兩個冬至之間有幾個朔望月,如果是12個朔望月,則不置閏,如果是十三個朔望月,則置閏月,至于閏幾月,則要看節(jié)氣而定。對于有13個朔望月的農(nóng)歷年,置閏月的規(guī)則就是從農(nóng)歷二月開始到十月,第一個沒有中氣的月就是閏月,這個沒有中氣的朔望月跟在哪個月后面就是閏幾月。為什么會有沒有中氣的朔望月呢?黃道上兩個中氣之間相隔30度,一個回歸年的長度是365.2422日,則兩個中氣之間的平均間隔是365.2422 12 = 30.4368日,但是因為地球軌道是橢圓軌道,因此相鄰的兩個中氣的時間間隔是不均勻的,比如在遠地點附近的中氣間隔就會長一點,最長可能是31.45天。而農(nóng)歷的朔望月平均長度是29.5306日,這樣就會出現(xiàn)某個朔望月剛好落在兩個中氣之間的情況,比如,某個月的上一個月月末是一個中氣,但是下一個中氣落在這個月的下一個月的頭幾天里,這樣這個月就沒有中氣了。舉個例子,2001年農(nóng)歷辛已年的四月二十九(公歷5月21日)是小滿,農(nóng)歷四月之后的這個朔望月從公歷5月23日持續(xù)到公歷6月20日,而小滿后的下一個中氣夏至是在公歷的6月21日,也就是農(nóng)歷四月的下下個月的初一,這樣農(nóng)歷四月后的這個月就沒有中氣,跟在四月之后,就稱為閏四月。
由于節(jié)氣在回歸年中是均勻分布的,因此公歷中的節(jié)氣日期基本上是固定的,比如立春是在公歷的2月3-5日,不會超出這個日期范圍,這也就是《二十四節(jié)氣歌》所說的:每月兩節(jié)不變更,最多相差一兩天。但是在中國農(nóng)歷中哪個中氣屬于哪個月是有規(guī)定的,雨水是正月的中氣,春分是二月的中氣,谷雨是三月的中氣,小滿是四月的中氣,夏至是五月的中氣,大暑是六月的中氣,處暑是七月的中氣,秋分是八月的中氣,霜降是九月的中氣,小月是十月的中氣,冬至是十一月的中氣,大寒是十二月的中氣。
在了解了農(nóng)歷與節(jié)氣的關系以及農(nóng)歷如何置閏月的方法之后,還需要解決一個問題才能著手農(nóng)歷年歷的推算,那就是如何確定農(nóng)歷年的開始,或者說哪個月的初一是農(nóng)歷新年的開始?要回答這個問題,就需要了解中國農(nóng)歷特有的“月建”問題。
中國農(nóng)歷是陰陽合歷,需要同時考慮太陽和月亮的位置。所以在確定歲首(元旦)時,需要先確定它在某個季節(jié),然后再選定與這個季節(jié)相近的朔望月作為歲首。由于一歲(一個回歸年)和12個陰歷月并不相等,相差約10.88天,因此每隔三年需要設置一個閏月調(diào)整季節(jié)。中國上古的天文學家想出了一個簡便的方法判斷月序與季節(jié)的關系,這就是以傍晚時北斗七星的斗柄的指向確定月序,稱為“十二月建”。從北方起向東轉(zhuǎn),將地面劃分為十二個方位,傍晚時北斗所指的方位,就是該月的月建,其子月為冬至所在之月,對應十一月,丑月是冬至所在之月的次月,對應十二月,寅月在丑月之后,對應正月。中國在歷史上的不同時期,多次修改過歲首(元旦)的起始月份,上古時代就有“三正”之說,所謂“三正”,就是“夏正建寅、殷正建丑、周正建子”,意思是夏歷以寅月(正月)為歲首,殷歷以丑月(十二月)為歲首,周歷以子月(十一月)為歲首。從秦代到西漢前期又采用秦歷,秦歷建亥,也就是以亥月作為歲首之月,漢武帝太初元年(公元104年)改用太初歷,重新適用建寅的夏歷,以寅月(正月)為歲首。在這之后的兩千多年時間里,除王莽和魏明帝一度改用建丑的殷歷,唐武后和肅宗時改用建子的周歷外,各個朝代均使用建寅的夏歷直到清朝末年。辛亥革命勝利以后,南京國民政府將公歷1月1日改為元旦,但是人們?nèi)粤晳T稱農(nóng)歷的正月初一為元旦。新中國成立初期召開的第一屆政治協(xié)商會議,正式將公歷的1月1日確定為元旦,將農(nóng)歷的正月初一定為“春節(jié)”,也就是說,農(nóng)歷的歲首仍然采用夏歷從寅月(正月)開始。
了解了“月建”問題,就解決了農(nóng)歷朔望月與公歷月的對應關系,那就是冬至節(jié)氣所在的朔望月就是農(nóng)歷的子月,對于目前適用的夏歷建寅的月建體系,就意味著冬至節(jié)氣所在的朔望月是農(nóng)歷的十一月,只要找到這個朔望月的起始日(日月合朔發(fā)生的時刻所在的那一日),就找到了公歷的日期月農(nóng)歷日期的對應關系。下面總結(jié)一下中國農(nóng)歷歷法的基本法則:
1、嚴格以日月合朔發(fā)生時刻為月首,這一天定為初一,通過計算兩次日月合朔的時間間隔確定每月是29天還是30天;
2、月以中氣得名,冬至節(jié)氣總是出現(xiàn)在農(nóng)歷十一月,包含雨水中氣的月為正月(即寅月),月無中氣者為閏月,與前一個月同名;
3、從某一年的冬至后第一天開始,到下一個冬至這段時間內(nèi),如果有十三個朔望月出現(xiàn),則此期間要增加一個閏月,從二月到十月,第一個沒有中氣的月就是閏月,如果在此期間有超過兩個朔望月沒有中氣,則只有第一個沒有中氣的朔望月是閏月;
4、農(nóng)歷年以正月初一為歲首(關于農(nóng)歷歲首的說法,請參考文末附加的《小知識5:正月初一和立春節(jié)氣》),以臘月(十二月)廿九或三十為除夕;
5、如果節(jié)氣和日月合朔在同一天,則該節(jié)氣是這個新朔望月的節(jié)氣。(民間歷法)
規(guī)則5對節(jié)氣和朔日在同一天的處理,采用了民間歷法的處理原則,關于民間歷法和歷理歷法的區(qū)別,請參考文末附加的《小知識1:民間歷法和歷理歷法》。
了解了農(nóng)歷歷法的基本法則后,就可以根據(jù)歷法進行農(nóng)歷年歷的推算。農(nóng)歷年歷的推算是一件很復雜的事情,需要知道每年二十四個節(jié)氣和本年內(nèi)每次日月合朔的精確時間,這些時間的獲取比較困難?,F(xiàn)在有很多可以顯示農(nóng)歷的日歷軟件,其實并不計算這些時間,而是事先從權(quán)威機構(gòu)(如紫金山天文臺)獲取這些經(jīng)過推算的時間,然后用各種方法將這些信息存儲在設計好的數(shù)據(jù)結(jié)構(gòu)中。當計算農(nóng)歷時采用查表的方法獲取每年的二十四節(jié)氣日期、大小月情況以及閏月情況,這樣的軟件受數(shù)據(jù)量的限制,往往只能顯示近一兩百年的年歷。
還有一種確定節(jié)氣時間和朔日時間的方法,就是在已知某個節(jié)氣或朔日的精確時間后,通過某些規(guī)律先前或向后推算其它節(jié)氣或朔日的時間。有一些經(jīng)驗公式可以用來計算節(jié)氣發(fā)生的日期,比如“通式壽星公式”,可以計算出某一年的某個節(jié)氣時間,但是只能精確到日。關于“通式壽星公式”的詳細內(nèi)容,請參考文末附加的《小知識2:通式壽星公式》。至于精確的節(jié)氣或朔日時間,也只能從權(quán)威機構(gòu)獲取。以節(jié)氣的時間推算為例,二十四個節(jié)氣就是黃道上的24各點,由于地球運動受其它天體的影響,導致這些節(jié)氣在每年的時間是不固定的,但是這些節(jié)氣之間的間隔時間基本上可以看作是固定的,下表就是二十四節(jié)氣的時間間隔表:
節(jié)氣名 | 與上一節(jié)氣之間的時間差 | 與小寒節(jié)氣的累積時間差 |
小寒 | 1271448.00 | 0.00 |
大寒 | 1272494.40 | 1272494.40 |
立春 | 1275526.20 | 2548020.60 |
雨水 | 1282123.20 | 3830143.80 |
驚蟄 | 1290082.80 | 5120226.60 |
春分 | 1300639.20 | 6420865.80 |
清明 | 1311153.00 | 7732018.80 |
谷雨 | 1323253.80 | 9055272.60 |
立夏 | 1333685.40 | 10388958.00 |
小滿 | 1344107.40 | 11733065.40 |
芒種 | 1351227.00 | 13084292.40 |
夏至 | 1357299.60 | 14441592.00 |
小暑 | 1358968.80 | 15800560.80 |
大暑 | 1358786.40 | 17159347.20 |
立秋 | 1354419.00 | 18513766.20 |
處暑 | 1348236.00 | 19862002.20 |
白露 | 1339003.20 | 21201005.40 |
秋分 | 1328654.40 | 22529659.80 |
寒露 | 1317185.40 | 23846845.20 |
霜降 | 1305760.80 | 25152606.00 |
立冬 | 1295081.40 | 26447687.40 |
小雪 | 1285764.00 | 27733451.40 |
大雪 | 1278469.80 | 29011921.20 |
冬至 | 1273556.40 | 30285477.60 |
表(1)二十四節(jié)氣時間間隔表(單位:秒鐘)
已知1900年小寒時刻為1月6日2:05:00,以這個節(jié)氣時刻為基準,推算其它年份節(jié)氣的算法實現(xiàn)如下:
8 static double s_stAccInfo[] = 9 { 10 0.00, 1272494.40, 2548020.60, 3830143.80, 5120226.60, 6420865.80, 11 7732018.80, 9055272.60, 10388958.00, 11733065.40, 13084292.40, 14441592.00, 12 15800560.80, 17159347.20, 18513766.20, 19862002.20, 21201005.40, 22529659.80, 13 23846845.20, 25152606.00, 26447687.40, 27733451.40, 29011921.20, 30285477.60 14 }; 15 16 //已知1900年小寒時刻為1月6日02:05:00 17 const double base1900_SlightColdJD = 2415025.5868055555; 18 19 double CalculateSolarTermsByExp(int year, int st) 20 { 21 if((st < 0) || (st > 24)) 22 return 0.0; 23 24 double stJd = 365.24219878 * (year - 1900) + s_stAccInfo[st] / 86400.0; 25 26 return base1900_SlightColdJD + stJd; 27 28 } |
base1900_SlightColdJD是北京時間1900年1月6日凌晨2:05:00的儒略日數(shù),CalculateSolarTermsByExp()函數(shù)返回指定年份的節(jié)氣的儒略日數(shù)。已知某個朔日的精確時間推算其它朔日時間的方法也類似,以朔望月的長度為單位向前或向后累加即可。
這種推算的方法是建立在地球回歸年的長度是固定365.2422天、節(jié)氣的間隔是絕對固定的、朔望月長度是平均的29.5305天等假設之上的,由于天體運動的互相影響,這種假設不是絕對成立的,因此這種推算方法的誤差很大。以CalculateSolarTermsByExp()函數(shù)為例,計算1900年前后30年內(nèi)的節(jié)氣時間的誤差還可以控制在30分鐘以內(nèi),但是到2000年的時候誤差已經(jīng)超過130分鐘了。人們還總結(jié)出了計算節(jié)氣和朔日時間的兩個經(jīng)驗公式,本文末尾附加的《小知識3:計算節(jié)氣和朔日的經(jīng)驗公式》一節(jié)會詳細介紹這兩個公式,不過這兩個公式的結(jié)果也只能精確到日,不能提供10秒以內(nèi)精度的時間。要想精確地獲得幾千年乃至更長時間范圍內(nèi)任意一年的節(jié)氣發(fā)生時間和日月合朔時間,就只能采用“天文算法”。
《繼續(xù):天文算法計算農(nóng)歷。。。》