「兩千年中西曆轉換」資料庫介紹

邱展毅

  編按:「兩千年中西曆轉換」目前已開放給網路上所有使用者使用,其位置放在中央研究院首頁(Home Page)下的「研究成果及各式資訊」內(URL為http://www.sinica.edu.tw/ftms/luso.htm),歡迎有興趣者上線使用。

前言

  對文史方面的研究人員而言,可能經常需要使用中曆與西曆的對照資料,而目前可以提供中西曆對照的工具,不外乎各種萬年曆對照表或中西曆對照表等工具書。這些書少則一、二百頁,多則上千頁,既不便於攜帶,更不易快速查詢。此外,這些工具書所提供的資料可能並不十分完整,或只能在圖書館內查閱,而無法滿足立即查詢的需求。

  生活在網路與通訊快速發展的資訊時代,若能在網路上快速取得中西曆對照資料,相信是許多人所企盼的。「兩千年中西曆轉換」即是在這股資訊浪潮衝擊下的產物,它協助我們快速而方便的取得完整的中西曆對照資料。根據我們的瞭解,這可能是目前涵蓋期間最長久,提供訊息最完整的中西曆轉換程式。其轉換的範圍由西元元年(西漢平帝元始一年)至西元兩千年(民國八十九年),所具備的功能除了可直接由西曆日期查詢對應的中曆朝代、帝號、年號、年干支、年、月、日等資訊外,亦可直接以中曆之朝代、帝號、年號、年干支、日干支...等資料查詢對應的西曆日期。除了上述的功能之外,我們特別在兩千年中西曆轉換程式中加入中西對照的「月曆功能」【註一】。希望這個程式除了對文史方面的研究人員有所助益外,亦能滿足其他對中西曆轉換有興趣者的需求。

 

製作緣起

  由於在協助經濟所王業鍵院士處理清代糧價清單的過程中,需要將明朝末年至清朝末年這段期間的中曆日期對照為西曆日期。且由於清代糧價清單在中曆日期部份需使用「朝代」、「帝號」、「年號」、「年干支」等資料,而目前電腦上並無這類的工具可供使用,因而著手進行中西曆轉換程式的開發工作。

  當設計中西曆轉換程式時,我們認為與其僅侷限於清代兩、三百年之間,不如擴充其架構,以整個中國歷史期間為標的。這麼做程式的複雜度並不會增加太多,且資料結構幾乎不需再做調整。因此,我們先依據薛仲三、歐陽頤兩位先生所編著的「兩千年中西曆對照表」建立基本的對照資料,並暫將本程式命名為「兩千年中西曆轉換」。

 

中國曆與西洋曆的規則

  撰寫中西曆轉換程式時,有必要對中國曆法與西洋曆法的運算規則與特例作進一步的瞭解,以期能正確的推算出中西曆對應的日期。以下分別說明程式中所使用的運算規則,並介紹幾個中國曆與西洋曆的特例。

一、西洋曆的運算規則

  西洋曆的計算規則較為單純,主要的重點為閏年的計算。其運算規則為:「西元年被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

 

 

1

2

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)的記憶體空間。

 

  基於上述理由,我們仔細評估該以何種資料結構來表示中西曆日期的對應關係,下圖即是我們使用的結構:

 

閏幾月

1

2

3

4

5

6

7

8

9

10

11

12

13

 

  上圖記錄每個中曆年的相關資料,圖中共有16個欄位,前兩個欄位(月、日)為中曆每年的第一天所對應的西曆日期;第三個欄位(閏幾月)說明該中曆年那一個月為閏月;最後十三個欄位,分別表示各個中曆月份(含閏月)是大月(30天)或小月(29天)。若每個欄位皆以2個位元組的短整數變數來儲存,需使用64KB(2*16*2000)的記憶空間,較之前的方法(6MB)節省了甚多的空間。

 

  由上圖的資料結構中,讀者也許會覺得奇怪,為何不用記錄「年」這個資料?原因很簡單,由於中西曆之間存在一對一的年序對應關係,可以直接將西元年視為中曆年序。所有的中曆對照資料依年序自小而大排列,在這個排列順序上已經隱含了年序的概念。排除年序的結果,導致每筆資料經過程式轉換後,可以擺入4bytes的空間內,非常便於程式的操作。我們只需知道中西曆轉換的起始對照日期(起始西曆年、月、日、星期及對應的起始中曆年干支、日干支)【註三】,即可依每筆記錄的大小月及閏月資料,逐年往後推算出各中曆年的第一天所對應的西曆日期。例如,兩千年中西曆轉換由西漢平帝元始一年一月一日(西元元年2月11日星期六)開始記錄,則其對應的資料結構如下:

 

2

11

0

1

0

1

0

1

0

1

1

0

1

0

1

0

2

1

8

0

1

0

1

0

1

0

1

0

1

0

1

1

2

20

0

0

1

0

1

0

1

0

1

0

1

0

1

0

2

5

0

1

1

0

0

1

0

0

1

0

1

1

0

0

 

  「基本對照資料」建立程式,就是要將資料輸入者依上述資料結構所輸入的每一筆記錄(一筆記錄儲存一個中曆年資料),以一個32位元的整數(integer)變數來儲存,以節省更多的記憶體空間。下圖即是以一個32位元的整數來記錄中曆(農曆)民國84年與西曆日期的對照關係:

 

1

31

8

0

1

1

0

1

0

1

1

0

0

1

0

1

 

  上圖中,前兩個欄位分別以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為http://cssun18.cs.ccu.edu.tw/~csiehtml/tools/tools.html)所提供的「新曆農曆轉換」功能,只能作民國以後的中西曆轉換;而其「萬年曆」功能,亦只提供西洋曆的月曆功能。此外,在UNIX上常用的日期查詢工具---cal指令,只能作西洋曆的查詢,並無中西曆對照功能。「兩千年中西曆轉換」不僅含蓋這兩個工具的功能,更提供了以中曆為主軸及以西曆為主軸的兩種「中西對照月曆功能」。

二、國立成功大學物理系之「中國天文學發展簡史」首頁(URL為http://phyhp.phy.ncku.edu.tw/~htsu/astron_chinese/astron_chinese.html),對中國古代天文學的發展、陽曆、陰曆及二十四節氣有概略的說明,有興趣的讀者可自行上網參考。

三、「兩千年中西曆轉換」之起始日期為:西元元年二月十一日星期六,相當於中國曆之西漢平帝元始一年歲次辛酉一月一日(日干支為「己未」)。