[2010-09-20].NET 2.0 C#下利用ChineseLunisolarCalendar类农历的实现

题外话:第一次在CSDN上发日志文章,因为一直在用的QQ空间和163博客都不支持代码段的插入,毕竟大家的定位也不同,QQ和163定位于门户性社区,所以以后还是尽量把技术性的东西往技术性社区放好了。

 

好了,言归正传,农历的实现一般都是自己写代码计算相关的时差,.NET 2.0则提供了一个农历的类库(看来微软终于发现中国的存在了)。这个类库在System.Globalization命名空间下,名称是ChineseLunisolarCalendar,这个类引用MSDN上的原文解释为:

将时间分成多个部分来表示,如分成年、月和日。年按农历计算,而日和月按阴阳历计算。

呵呵,“日和月按阴阳历计算”,不知道是什么意思,反正最终出来的计算结果是对的,我也没有深究。

 

ChineseLunisolarCalendar类提供了方法直接把当前日期换算成农历。

如常用的:

GetYear():返回了一个1到60之间的整数,至于为什么是1到60,有兴趣的可以自行了解一下农历的计算原理或者研究一下命理测算(估计研究完这个你就不用程序展示农历给你看,自己能心算了。)

GetMonth():返回一个 1 到 13 之间的整数,同理的研究一下农历计算原理或跟算命的了解一下,就知道为什么农历会有13个月。

GetDayOfMonth():返回一个从 1 到 31 的整数。

还有一些与Leap相关的方法和属性是与闰月相关的,也会经常用到。

下面看一下实际代码:

using System; using System.Collections.Generic; using System.Text; using System.Globalization; using System.Collections; namespace LunarCalendar { public class C_LunarCalendar { ///

/// 农历年份 /// private static String[] ChinaYear = new String[]{ "甲子","乙丑","丙寅","丁卯","戊辰","己巳","庚午","辛未","壬申","癸酉","甲戌","乙亥", "丙子","丁丑","戊寅","己卯","庚辰","辛巳","壬午","癸未","甲申","乙酉","丙戌","丁亥", "戊子","己丑","庚寅","辛卯","壬辰","癸巳","甲午","己未","丙申","丁酉","戊戌","己亥", "庚子","辛丑","壬寅","癸卯","甲辰","乙巳","丙午","丁未","戊申","己酉","庚戌","辛亥", "壬子","癸丑","甲寅","乙卯","丙辰","丁巳","戊午","己未","庚申","辛酉","壬戌","癸亥" }; /// /// 农历月份 /// private static String[] ChinaMonth = new String[]{ "元", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "腊" }; /// /// 农历日期 /// private static String[] ChinaDay = new String[]{ "初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十", "十一", "十二","十三", "十四" ,"十五", "十六","十七", "十八" ,"十九", "二十", "廿一", "廿二","廿三", "廿四" ,"廿五", "廿六","廿七", "廿八" ,"廿九", "三十" }; /// /// 十二生肖 /// private static String[] ChinaZodiac = new String[] { "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" }; private static Hashtable aChinaFestival_LC = new Hashtable(); /// /// 农历类对象 /// private static ChineseLunisolarCalendar aLunisolarCalendar_C = new ChineseLunisolarCalendar(); /// /// 错误信息 /// private static String aErrMsg = ""; /// /// 农历的年 /// private static Int32 aYear_Lc; /// /// 农历的月 /// private static Int32 aMonth_Lc; /// /// 农历的日 /// private static Int32 aDay_Lc; public static String ErrMsg { get { return aErrMsg; } } static C_LunarCalendar() { aChinaFestival_LC.Add("腊三十", "除夕"); aChinaFestival_LC.Add("元初一", "春节"); aChinaFestival_LC.Add("元十五", "元宵"); aChinaFestival_LC.Add("四十六", "清明"); aChinaFestival_LC.Add("五初五", "端午"); aChinaFestival_LC.Add("七初七", "七夕"); aChinaFestival_LC.Add("九初九", "重阳"); aChinaFestival_LC.Add("七十五", "中元"); aChinaFestival_LC.Add("八十五", "中秋"); aChinaFestival_LC.Add("腊初八", "腊八"); } public static Boolean GetLunisolarCalendarForChina(DateTime CurrentDateTime,out String DateTime_LC) { DateTime_LC = ""; if (CurrentDateTime > aLunisolarCalendar_C.MaxSupportedDateTime || CurrentDateTime < aLunisolarCalendar_C.MinSupportedDateTime) { aErrMsg = "不被支持的日期!"; return false; } aYear_Lc = aLunisolarCalendar_C.GetYear(CurrentDateTime); aMonth_Lc = aLunisolarCalendar_C.GetMonth(CurrentDateTime); aDay_Lc = aLunisolarCalendar_C.GetDayOfMonth(CurrentDateTime); Boolean iIsLeap = aLunisolarCalendar_C.IsLeapMonth(aYear_Lc, aMonth_Lc); if (iIsLeap) aMonth_Lc -= 1; StringBuilder iChinaDateTimeStr = new StringBuilder(); Int32 iYearID = (aYear_Lc - 4) % 60; iChinaDateTimeStr.Append(ChinaYear[iYearID]); iChinaDateTimeStr.Append("年 "); if (iIsLeap) iChinaDateTimeStr.Append("闰" + ChinaMonth[aMonth_Lc - 1] + "月 "); else iChinaDateTimeStr.Append(ChinaMonth[aMonth_Lc - 1] + "月 "); iChinaDateTimeStr.Append(ChinaDay[aDay_Lc - 1]); DateTime_LC = iChinaDateTimeStr.ToString(); return true; } /// /// 取指定日期的农历日 /// /// 当前日期 /// 如果为月份的第一天是否返回月份字符串 /// 是否返回节日(比月份优先返回) /// public static String GetLCDayForChina(DateTime CurrentDateTime, Boolean IfRetMonthInFistDay, Boolean IfRetFestival) { if (CurrentDateTime > aLunisolarCalendar_C.MaxSupportedDateTime || CurrentDateTime < aLunisolarCalendar_C.MinSupportedDateTime) { aErrMsg = "不被支持的日期!"; return ""; } String iMonthStr; aDay_Lc = aLunisolarCalendar_C.GetDayOfMonth(CurrentDateTime); if (IfRetFestival) { iMonthStr = GetLCMonthForChina(CurrentDateTime); if (aChinaFestival_LC.Contains(iMonthStr + ChinaDay[aDay_Lc - 1])) return aChinaFestival_LC[iMonthStr + ChinaDay[aDay_Lc - 1]].ToString(); } if ((aDay_Lc == 1) && IfRetMonthInFistDay) { iMonthStr = GetLCMonthForChina(CurrentDateTime); if (aLunisolarCalendar_C.IsLeapMonth(CurrentDateTime.Year, CurrentDateTime.Month)) return String.Format("闰{0}月", iMonthStr); else return String.Format("{0}月", iMonthStr); ; } return ChinaDay[aDay_Lc - 1]; } /// /// 取指定日期的农历年 /// /// 当前日期 /// public static String GetLCYearForChina( DateTime CurrentDateTime ) { if (CurrentDateTime > aLunisolarCalendar_C.MaxSupportedDateTime || CurrentDateTime < aLunisolarCalendar_C.MinSupportedDateTime) { aErrMsg = "不被支持的日期!"; return ""; } Int32 iYear = aLunisolarCalendar_C.GetYear(CurrentDateTime); iYear = (iYear - 4) % 60; return ChinaYear[iYear]; } /// /// 取指定日期的农历月 /// /// 当前日期 /// public static String GetLCMonthForChina(DateTime CurrentDateTime) { if (CurrentDateTime > aLunisolarCalendar_C.MaxSupportedDateTime || CurrentDateTime < aLunisolarCalendar_C.MinSupportedDateTime) { aErrMsg = "不被支持的日期!"; return ""; } Int32 iMonth = aLunisolarCalendar_C.GetMonth(CurrentDateTime); Int32 iYear = aLunisolarCalendar_C.GetYear(CurrentDateTime); Boolean iLeapYear = aLunisolarCalendar_C.IsLeapYear(iYear); if (iLeapYear) { Int32 iLeapMonth = aLunisolarCalendar_C.GetLeapMonth(CurrentDateTime.Year); if (iMonth >= iLeapMonth) iMonth--; } return ChinaMonth[iMonth - 1]; } /// /// 取指定年的生肖 /// /// 指定年的日期 /// public static String GetLCYearZodiac(DateTime CurrentDateTime) { if (CurrentDateTime > aLunisolarCalendar_C.MaxSupportedDateTime || CurrentDateTime < aLunisolarCalendar_C.MinSupportedDateTime) { aErrMsg = "不被支持的日期!"; return ""; } Int32 iYear = aLunisolarCalendar_C.GetSexagenaryYear(CurrentDateTime); iYear = aLunisolarCalendar_C.GetTerrestrialBranch(iYear); return ChinaZodiac[iYear - 1]; } } }

 

这个类并没有整理过,只是要用什么才随便写个方法,所以代码比较乱。

 

利用这个类,做了一个农历月历,效果如下:

 

 

 

月历上可以看出,没有传统节日,以后会加上。

另外也提前祝大家中秋节快乐,合家团圆!

 

2010-12-03

+个下载地址:

http://download.csdn.net/source/2880958

你可能感兴趣的:(C#相关)