关于TMoon中的公历农历算法.
以下内容是从控件Moon component中摘录出来的,随后是笔者的译文(有感于E文太差,如有不当,指正,见谅)
Chinese Date
Algorithms See also
Converts a Delphi TDatetime to the chinese date and back.
function ChineseDate(date: TDateTime):TChineseDate;
function EncodeDateChinese(date: TChineseDate):TDateTime;
Description
The chinese calendar is a lunisolar calendar like the jewish calendar, however the main difference is that the chinese calendar uses the astronomical events, and not a approximate algorithm. Another difference is that the chinese calendar uses the actual new moon, not the visibility of the first crescent as the jewish or muslim calendar.
描述
中国农历和犹太历一样,也是阴阳合历,然而其主要不同的是,中国农历使用天文事件,而不是近似的算法.另外的不同点是,中国农历使用实际的新月,而不是像犹太历或穆罕默德历(伊斯兰教历)那样使用可见到的第一个新月(作为月的起始).
The chinese datedo
es not have a continous year count, but instead it is counted in 60 year long cycles. Every year in this cycle belongs to one of 10 heavenly stem and one of the 12 earthly branches, which is the name of zodiac for the given year. So the year in TChineseDate is encoded in the cycle number and the year number, and for information it also has the stem and the zodiac of the year. The similar sexagenary cycle for months and days is only rarely used anymore, however it is also calculated.
中国农历没有连续的纪年, 取而代之的是60年一循环.循环中的每个纪年由10天干和12地支组成,(其实十二地支与黄道十二宫名称是相类似的).所以年属性TChineseDate在对循环年序号进行编码,以提供该年的天干地支信息.和年相类似,月与日也是以此六十循环,但已经很少使用,不管如何,这里也进行了计算.
As the chinese calendar is lunarsolar it needs to introduce leap years, which contain a leap month. The leap month has the same number as the previous month, it only gets an additional flag to notice it's a leap month. In principle every month can be a leap month, however around the perihelion they are very unlikely.
正由于中国农历是阴阳合历,它需要引入闰年来加入闰月.闰月与其上一个月的天数相同,只是添加了一个标记来表示这是个闰月.原则上任何一个月都可以是闰月,然而,在近日点附近时并不可靠.
As the month starts on the day of the new moon (the day in Beijing), the length of the months can be either 29 or 30 days, sometimes with up to 4 long or 3 short months in a row, but usually changing every month.
由于月的起始是新月这一天(北京时间,注:每个时区的新月时间是不同的.),月的长度是29天或是30天,有时会有多4天到少3天(in a row是何指不甚清楚,是否是因为近日点的节气时间被拉长之帮?望指教),但是通常每月都在变.
The chinese calendar in its present form was introduced in 1645, but it had existed in similar versions long time before already. As it is based upon the astronomical events all the calculations here are correct as long as the basic astronomical algorithms aren't too much wrong, so using this calculation too far into the future will return meaningless results.
中国农历是在1645年出现的,但它的相似版本已经老早就有了.由于它是基于天文事件的,所有的计算长时间来与实际的相差不大.所以在太久远的未来使用此历法所返回的值将是毫无意义的.(呵呵,翻不来了,就这样吧,前句显然不对,望指正)
(就干支纪日来说,"农历日纪从鲁隐公三年(公元前722年)二月己巳日至今, 我国干支记日从未间断. 这是人类社会迄今所知的唯一最长的记日法。","<http://www.rltmw.com/netpage/10nl/nlrjgl.html>",另外: "<http://culture.luneng.com/culture/2002/0110/20020110050.htm>" 中国古代历法发展;
"<http://www.henan-window.com/tour/guanxt/index.html>"中国历法的改革与发展.)
The EncodeDateChinese function will raise an exception in case of an invalid date given - e.g. a leap month which is none, or a 30th on a month which only has 29 days. Note that it only uses the fields cycle, year, month, day and leap of the record, the other fields are not checked for the conversion.
Reference
These functions are based in part upon the book Calendrical Calculations.
http://emr.cs.iit.edu/home/reingold/calendar-book/index.shtml
上面的网址是作者编写公历农历互换函数的参考资料.
很费力能译过作者的说明后,我们看到,控件Moon component对于公历与农历的互换只对采用1946年的历法时才有意义,否则返回的结果就是以今人的历法来表示古人的时间(虽然古人采用的可能不是这个值),或者是以今人的历法强加于未来可能采用的农历历法,这也是毫无意义的.
所有的历法的制定,都是与天体的运行有着直接的关系,但期间又因各种原因有着各样的变更,随着科学的发展,社会的进步,历法在一步步的完善,改良,也可能会被当时代人以各种理由而修改,所以,求一个包含无穷的算法来计算和互换历法是不可能的,也是毫无意义的.除非你能预知前师后事.