三、农历类的使用

既然.net框架不支持直接将日期转换成农历格式的字符串,那么要将显示农历格式的日期,就只要自已写代码了。不过由于已经有了ChineseLunisolarCalendar类实现了公历转换为农历日期的功能,所以要写这样的代码也比较简单。需要用到ChineseLunisolarCalendar以下几个主要方法:

int GetYear (DateTime time) 获取指定公历日期的农历年份,使用的还是公历纪元。在每年的元旦之后春节之前农历的纪年会比公历小1,其它时候等于公历纪年。虽然农历使用传说中的耶稣生日纪元似乎不太妥当,不过我们确实已经几十年没有实行一个更好的纪年办法,也只有将就了。

int GetMonth (DateTime time) 获取指定公历日期的农历月份。这里要注意了,由于农历有接近三分之一的年份存在闰月,则在这些年份里会有十三个,而具体哪一个月是闰月也说不准,这里不同于希伯来历。以今年为例,今年闰七月,则此方法在参数为闰七月的日期是返回值为 8,参数为农历十二月的日期时返回值为13

bool IsLeapMonth ( int year,   int month) 获取指定农历年份和月份是否为闰月,这个函数和上个函数配合使用就可以算出农历的月份了。

int GetDayOfMonth (DateTime time) 获取指定公历日期的农历天数,这个值根据大月或者小月取值是130或者129, MSDN上说的131显然是错的, 没有哪个农历月份会有31天。

int GetSexagenaryYear (DateTime time) 获取指定公历日期的农历年份的干支纪年,从160,分别是甲子、乙丑、丙寅、….癸亥, 比如戊戌变法、辛亥革命就是按这个来命名的。当然算八字也少不了这个。

int GetCelestialStem (int sexagenaryYear) 获取一个天支的天干, 110, 表示甲、乙、丙….,说白了就是对10取模。

int GetTerrestrialBranch (int sexagenaryYear) ) 获取一个干支的地支,, 112, 表示子、丑、寅、今年是狗年,那么今年年份的地支就是“戌”。

有了这几个方法,显示某天的农历月份日期、农历节日等都是小菜一碟,算命先生排八字用这几个方法,又快又准确,写出的代码也很短。
 

四、几种东亚农历类的区别

经过我的测试,ChineseLunisolarCalendar, JapaneseLunisolarCalendar, KoreanLunisolaCalendarr, TaiwanLunisolarCalendar这四种日历,无论哪一种,以200626日为参数,调用它们的GetMonth方法得到的结果都是1GetDayOfMonth得到的结果都是8。想想也是,我们过的端午节和韩国的不太可能不是一天。

但是调用GetYear方法得到结果就有区别了ChineseLunisolarCalendarKoreanLunisolarCalendar都返回2006,也就是公历纪年,TaiwanLunisolarCalendar的返回值是95,依然是民国纪年,JapaneseLunisolarCalendar的返回值是18, 平成纪年。

另外的一个区别是这四种日历的MinSupportedDateTimeMaxSupportedDateTime各不一样,以下是对照表:

日历类 MinSupportedDateTime MaxSupportedDateTime
ChineseLunisolarCalendar 公元19011月初1 公元21001229
TaiwanLunisolarCalendar 民国11月初1 民国1391229
JapaneseLunisolarCalendar 昭和351月初1 平成611229
KoreanLunisolarCalendar 公元9181月初1 公元20501229

韩国农历类支持的最小日期为918(也即高丽王朝建立的年份),以此而论,中国农历类支持的最小日期不说从商周算起,从汉唐算总该没问题吧?微软公司啊,又在“厚彼薄此”,唉。

其次,日本还以天皇纪年,如果哪天xxxx, 岂不是使用JapaneseLunisolarCalendar写出的程序都有问题啦?