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 date does 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.
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.
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
上面的网址是作者编写公历农历互换函数的参考资料.