轉自:~tdbproj/sinocal/lusodoc.html
「兩千年中公歷轉換」數據庫介紹
(作者:邱展毅jychiou@sinica.edu.tw)
編按:「兩千年中公歷轉換」目前已開放給網絡上所有用戶使用,其位置放在中央研究院首頁(Home Page)下的「研究成果及各式信息」內(URL為),歡迎有興趣者上線使用。
前言
對文史方面的研究人員而言,可能經常需要使用中歷與公歷的對照資料,而目前可以提供中公歷對照的工具,不外乎各種萬年歷對照表或中公歷對照表等工具書。這些書少則一、二百頁,多則上千頁,既不便于攜帶,更不易快速查詢。此外,這些工具書所提供的數據可能并不十分完整,或只能在圖書館內查閱,而無法滿足立即查詢的需求。
生活在網絡與通訊快速發展的信息時代,若能在網絡上快速取得中公歷對照數據,相信是許多人所企盼的。「兩千年中公歷轉換」即是在這股信息浪潮沖擊下的產物,它協助我們快速而方便的取得完整的中公歷對照數據。根據我們的了解,這可能是目前涵蓋期間最長久,提供訊息最完整的中公歷轉換程序。其轉換的范圍由公元元年(西漢平帝元始一年)至公元兩千年(民國八十九年),所具備的功能除了可直接由公歷日期查詢對應的中歷朝代、帝號、年號、年干支、年、月、日等信息外,亦可直接以中歷之朝代、帝號、年號、年干支、日干支...等數據查詢對應的公歷日期。除了上述的功能之外,我們特別在兩千年中公歷轉換程序中加入中西對照的「月歷功能」【注一】。希望這個程序除了對文史方面的研究人員有所幫助外,亦能滿足其他對中公歷轉換有興趣者的需求。
制作緣起
由于在協助經濟所王業鍵院士處理清代糧價清單的過程中,需要將明朝末年至清朝末年這段期間的中歷日期對照為公歷日期。且由于清代糧價清單在中歷日期部份需使用「朝代」、「帝號」、「年號」、「年干支」等數據,而目前計算機上并無這類的工具可供使用,因而著手進行中公歷轉換程序的開發工作。
當設計中公歷轉換程序時,我們認為與其僅局限于清代兩、三百年之間,不如擴充其架構,以整個中國歷史期間為標的。這么做程序的復雜度并不會增加太多,且數據結構幾乎不需再做調整。因此,我們先依據薛仲三、歐陽頤兩位先生所編著的「兩千年中公歷對照表」建立基本的對照數據,并暫將本程序命名為「兩千年中公歷轉換」。
中國歷與西洋歷的規則
撰寫中公歷轉換程序時,有必要對中國歷法與西洋歷法的運算規則與特例作進一步的了解,以期能正確的推算出中公歷對應的日期。以下分別說明程序中所使用的運算規則,并介紹幾個中國歷與西洋歷的特例。
一、西洋歷的運算規則
西洋歷的計算規則較為單純,主要的重點為閏年的計算。其運算規則為:「公元年被4整除且不被100整除,或被400整除者即為閏年」。此一運算規則是現代人日常生活中耳熟能詳的,且經常在許多計算器程序語言的書中被引用。不過,可能少有人注意到西洋歷中存在的特例(受皇帝、教皇...等因素的影響),且上述閏年的運算規則亦不是一開始就是如此,而是經過校正調整而來的。根據「兩千年中公歷對照表」的說法,公歷有下列特例:
1.公歷4年(該年為閏年:被4整除且不被100整除),因羅馬皇帝「奧古斯都帝」停閏,故該年二月只有二十八天,而非二十九天。
2.教皇「格勒哥里第十三」改歷,以公元1582年10月5日為15日,中間略過10天,亦即公元1582年少了10/5-10/14這十天。
3.公元1582年以前的閏年計算規則:「被4整除者即為閏年」。所以,公元100年、200年、300年...、1400年、1500年皆為閏年。
4.公元1582年以后的閏年計算規則,即現今大家耳熟能詳的「被4整除且不被100整除,或被400整除者」。例如,公元1700年、1800年、1900年皆不是閏年,而公元16年、1984年、1996年皆為閏年。
上述西洋歷的特例情況,在兩千年中公歷轉換程序中已能正確處理。不過有一個事件必須在此提出說明:
在UNIX上有一個很方便的公歷日期查詢工具--cal指令,在其manual page內有一個注意事項,特別說明公歷1752年9月因為閏年校正的關系,將公元1752年9月3日改為9月14日,使得該月份少了11天。讀者可以在UNIX上輸入下列指令「cal 9 1752」,即可得到下列結果:
September 1752
Sun
Mon
Tue
Wed
Thu
Fri
Sat
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
這個情況顯然和「兩千年中公歷對照表」的講法有出入,兩者雖然都有十一天的校正,但分布時間及校正原因則不同。關于這個問題,我們很希望有文獻數據可以查證,為何會存在這個差異?若有讀者先進知道這個緣由,亦期盼能為筆者解惑。
二、中國歷的運算規則
中國歷法注重日、月的運行,日蝕與月蝕的推算,五大行星的出沒...等,可說是一部融合陽歷與陰歷精華,且十分精確的天文歷法【注二】。
中國歷法必須依據二十四節氣(與太陽及農作物生長息息相關)、朔望...等要素作推算。由于推算規則我們并不十分清楚,且因中國古代封建王朝的更迭、年號的變化及許多復雜政治因素的影響,使得中國歷存在許多特殊情形,必須在程序中以特例的方式處理。基于這些因素,在處理中歷部份時,我們并不采取規則推算的方式,改以基本數據配合精簡的數據結構,來完成中歷數據轉換的功能。
以下是我們所整理出從公歷1年至公歷2000年,這段期間所對應的中國歷之特例情形:
1.王莽以西漢孺子嬰初始元年十二月為其始建國元年的正月,故西漢孺子嬰初始元年少十二月(該年只有1-11月)。
2.西漢淮陽王更始元年,以王莽地皇4年11月為其更始元年之10月,因此西漢淮陽王更始元年有兩個10月(中公歷轉換程序以閏10月來處理第二個10月)。
3.前魏明帝景初元年,以該年之3月為4月,故是年無3月;至景初三年復寅正,因此前魏明帝景初三年有兩個12月(中公歷轉換程序以閏12月來處理第二個12月)。
4.唐武后(武則天)載初一年,以該年之11月為其天授元年的歲首,因此,唐武后載初元年只有10個月(缺11、12兩個月)。
5.唐武后久視一年10月復寅正,因此該年有兩個11月及兩個12月。
6.唐肅宗上元二年,以該年之11月為寶應元年之歲首,故上元二年只有10個月,而寶應元年有兩個11月及兩個12月。
除了上述之特例外,由于中國之年代久遠,歷經了多次朝代的分合更迭,因而有所謂的分裂時代(例如:春秋五霸、戰國七雄、三國之魏蜀吳、五代十國...)與統一時代(例如:唐、宋、元、明、清)之分。傳統史學家以分裂時代的某個王朝為正統(可能有爭議?),兩千年中公歷轉換程序循例以「兩千年中公歷對照表」一書之正統朝代為依據(例如該書視三國時代之魏為正統)。
程序架構與數據結構
兩千年中公歷轉換程序,由三個主要的程序模塊所組成,分別為「基本對照數據」、「中公歷轉換核心程序」及「Web接口程序(HTML與CGI)」,茲分述如下:
一、基本對照數據
兩千年中公歷數據的對應,若不謹慎思考日期對應的數據結構,可能會耗費大量的磁盤及內存空間。如此,不僅造成空間的浪費,更有可能因大量輸出入時間的延遲,而使得程序執行的效率不彰。下例是一個很直覺但占用較多內存空間的方法:
【方法】直接記錄中歷月日及公歷月日的對應。
【范例】中歷:清遜帝宣統三年(歲次辛亥)10月10日→公歷:公元1911年11月30日。
【使用空間】使用2個字節(byte)的短整數(short integer)變量來儲存中歷月、日(10月10日)及公歷月、日(11月30日),則兩千年的中公歷數據約需使用 6MB(4*2*365*2000)的內存空間。
基于上述理由,我們仔細評估該以何種數據結構來表示中公歷日期的對應關系,下圖即是我們使用的結構:
月
日
閏幾月
10
11
12
13
上圖記錄每個中歷年的相關數據,圖中共有16個字段,前兩個字段(月、日)為中歷每年的第一天所對應的公歷日期;第三個字段(閏幾月)說明該中歷年那一個月為閏月;最后十三個字段,分別表示各個中歷月份(含閏月)是大月(30天)或小月(29天)。若每個字段皆以2個字節的短整數變量來儲存,需使用64KB(2*16*2000)的記憶空間,較之前的方法(6MB)節省了甚多的空間。
由上圖的數據結構中,讀者也許會覺得奇怪,為何不用記錄「年」這個數據?原因很簡單,由于中公歷之間存在一對一的年序對應關系,可以直接將公元年視為中歷年序。所有的中歷對照數據依年序自小而大排列,在這個排列順序上已經隱含了年序的概念。排除年序的結果,導致每筆數據經過程序轉換后,可以擺入4bytes的空間內,非常便于程序的操作。我們只需知道中公歷轉換的起始對照日期(起始公歷年、月、日、星期及對應的起始中歷年干支、日干支)【注三】,即可依每筆記錄的大小月及閏月數據,逐年往后推算出各中歷年的第一天所對應的公歷日期。例如,兩千年中公歷轉換由西漢平帝元始一年一月一日(公元元年2月11日星期六)開始記錄,則其對應的數據結構如下:
11
20
.
.
.
「基本對照數據」建立程序,就是要將數據輸入者依上述數據結構所輸入的每一筆記錄(一筆記錄儲存一個中歷年數據),以一個32位的整數(integer)變量來儲存,以節省更多的內存空間。下圖即是以一個32位的整數來記錄中歷(農歷)民國84年與公歷日期的對照關系:
31
上圖中,前兩個字段分別以4個位(可儲存數字0~15)及5個位(可儲存數字0~31)來儲存中歷年的第一天所對應的公歷月日;第三個字段以4個位(可儲存數字0~15)來記錄中歷年第幾個月為閏月(此例為閏八月);第4到第16個字段分別以一個位(0或1)來表示各個月是大月(以1表示)或小月(以0表示)。如此,共使用了26個位,尚余6個位可供未來彈性使用。使用這個結構來儲存二千年中公歷對照數據,僅需使用8KB(4*2000)的記憶空間,不僅經濟實惠,更留給程序更多擴充的彈性。
除了上述數據結構外,還需要兩個表格以提供較完整的中公歷對照數據,這兩個表格為「朝代表」及「朝代年號表」。「朝代表」為中國每個朝代編號,供「朝代年號表」使用;而朝代年號表則記錄各個皇帝使用了那些年號及各個年號的起迄時間。稍后在「操作范例」中,讀者可以清楚的看出這兩個表格所提供的訊息。
二、中公歷轉換核心程序
這個部分是整個中公歷轉換的核心部分,由兩個主要的軟件組件構成,一為負責公歷日期差運算的組件,另一個組件負責中歷轉公歷及公歷轉中歷的相關細節。茲分別說明這兩個組件的功能:
(一)公歷日期差運算
這是一個獨立的軟件組件,它的主要功能如下:
1.由給定的日期往前或往后推算下一個日期。例如,1995年2月28日往后30天為1995年3月30日,而1995年3月30日往前30天為1995年2月28日。
2.求算二個日期間相差的天數。例如:1909年1月22日至1912年2月18日共經過了1122天(清朝最后一個皇帝溥儀在位的天數)。
3.求算某個月份的最后一天為幾號。例如:公元1996年2月的最后一天為29號,公元1997年2月的最后一天為28號。
(二)中公歷互轉
這個組件架在「公歷日期差運算」組件之上,配合「朝代表」、「朝代年號表」及上一節所介紹的「中公歷對照基本數據」,完成中歷轉公歷及公歷轉中歷的功能。例如:查詢「清光緒甲午年」,所得到的結果為「公元1894年2月6日至公元1895年1月25日」;查詢「公元27年4月1日」,所得到的結果為「東漢光武帝建武三年歲次丁亥閏二月六日」。
三、Web接口程序與CGI程序
兩千年中公歷轉換程序設計之初,除了設計中公歷轉換「核心程序」供清代糧價清單使用外,亦考慮將此功能開放到網絡上,供文史研究人員及有興趣的使用者使用。而目前正值全球信息網(WorldWide Web)盛行之時,圖形化的操作環境乃是時勢所趨。因此我們選用HTML(Hyper Text Markup Language)制作圖形化的輸入接口,并配合CGI(Common Getway Connection)程序,將中公歷轉換的結果,以圖形及表格的方式來顯示。
程序語言
兩千年中公歷轉換程序是以C++程序語言撰寫而成,此程序可以說是由一組獨立的軟件組件所組裝出來的產品。撰寫這支程序時,也正是Java程序語言席卷整個信息與電子世界之時。Java由原先被認為只是用來撰寫網絡上小程序(applet)的語言,蛻變為一個完整的程序語言。據悉,Java程序語言曾針對C++語言的缺點提出許多改良,且在個體導向(Object-Oriented)程序設計方面似乎又表現得較C++語言更為淋漓盡致。因此筆者在撰寫本文前,曾試著將兩千年中公歷轉換程序之部份模塊以Java程序語言改寫,并完成測試與執行。個人深覺只要具有C++語言程序設計經驗者,若能掌握住個體導向程序設計的觀念,要進入Java語言「程序設計」的領域,應該是一件輕松愉快的事!
操作范例
【圖一】即是「兩千年中公歷轉換」之輸入畫面。圖中清楚的切割為上下兩個區塊。上面的區塊為「公歷轉中歷」功能;下面的區塊為「中歷轉公歷」功能。這兩個功能皆提供兩種輸出結果,一為文本模式,另一種為表格模式(選取輸入畫面中的「顯示月歷」功能),讀者可視需求選擇所需的功能。
圖一 兩千年中公歷轉換程序輸入畫面
【范例一】查詢公元1023年1月所對應的中歷日期。
只要在「公歷轉中歷」輸入畫面中,輸入公歷年、月數據,并選取「顯示月歷」功能,即可得到【圖二】中公歷對照表格。由于公歷一個月通常都會跨二個中歷月份,使得同一個月可能存在朝代更換、年號變更、歲次(年干支)改變等情形,故在圖二上方加上說明文字,用來說明中公歷朝代、帝號、年號、歲次等對應關系。例如,本例中以兩列文字說明公元1023年1月1日(星期二)相當于「宋真宗干興1年歲次壬戌12月7日」;公元1023年1月25日(星期五)相當于「宋仁宗天圣1年歲次癸亥1月1日」。
圖二 公歷為主軸對照月歷
【范例二】查詢東漢光武帝建武丁亥年對應的公歷日期。
【圖三】即為以中歷為主軸的中西對照月歷。由表格中可以清楚的看出東漢光武帝建武丁亥年相當于建武三年,該年閏二月且于十一月十五日跨入公元28年。
圖三 中歷為主軸的對照年歷
【范例三】查詢東漢光武帝建武三年閏二月對應的公歷日期。
由【圖四】可以清楚的看出東漢光武帝建武三年閏二月與公歷日期的對應關系。例如:東漢光武帝建武三年閏二月六日相當于公元27年4月1日。
圖四 中歷為主軸的對照月歷
結語
看完上述的介紹后,您是否已迫不急待的想要上網一窺究竟,享受暢游古今中公歷轉換的樂趣?您可以查一查自己及親朋好友的出生日期(國歷或農歷),并確定一下自己是星期幾出生的?甚至您也可以拿著族譜依著「兩千年中公歷轉換」仔細對照增補一番。當然如果您是一位專業的文史研究學者,更希望這個程序對您的研究工作能有所幫助。
下一階段,我們計劃將「兩千年中公歷轉換」擴充為可以處理中國所有可考日期與公歷日期之間的轉換。例如,可以查詢商朝盤庚遷殷所對應的公歷日期,或公元前1000年相當于中國那個朝代、在位皇帝是誰、是那個年號、歲次(年干支)為何...等等,當然中國各分裂王朝的歷法與日期推算亦是我們努力的重點。希望能制作一個功能完整的中公歷轉換程序,更希望讀者先進能多多提供寶貴的意見,以期對文史研究能有更具體的貢獻。
致謝
在撰寫兩千年中公歷轉換程序時,感謝中心數據處理小組梁怡華小姐細心的建立「兩千年中公歷基本對照數據」,使得中公歷轉換程序得以順利進行。同時要感謝張佩宜小姐仔細的測試中公歷轉換功能,并提供許多寶貴的意見。在Web接口的制作方面,感謝賴彥丞及張錦堂兩位先生提供許多技術支持及改良的意見。此外,更要感謝林晰先生在中公歷轉換程序制作的過程中細心的指導與鼓勵,方使得本文得以順利完成。
注
一、國立中正大學資工館工具箱(URL為~csiehtml/tools/tools.html)所提供的「新歷農歷轉換」功能,只能作民國以后的中公歷轉換;而其「萬年歷」功能,亦只提供西洋歷的月歷功能。此外,在UNIX上常用的日期查詢工具---cal指令,只能作西洋歷的查詢,并無中公歷對照功能。「兩千年中公歷轉換」不僅含蓋這兩個工具的功能,更提供了以中歷為主軸及以公歷為主軸的兩種「中西對照月歷功能」。
二、國立成功大學物理系之「中國天文學發展簡史」首頁(URL為~htsu/astron_chinese/astron_chinese.html),對中國古代天文學的發展、陽歷、陰歷及二十四節氣有概略的說明,有興趣的讀者可自行上網參考。
三、「兩千年中公歷轉換」之起始日期為:公元元年二月十一日星期六,相當于中國歷之西漢平帝元始一年歲次辛酉一月一日(日干支為「己未」)。
上一篇:金木水火土婚配,五行命相婚配
下一篇:職場勵志電影