把阳历日期转换为农历用到的函数为ChinaDate.ConvertToNongLi(DateTime.Now);
得到节日的函数为 ChinaDate.GetFestival(DateTime.Now);
代码:
using System.Globalization;
using System.Collections;
using System;namespace NetWeb2011.Common
{public static class ChinaDate{private static ChineseLunisolarCalendar china = new ChineseLunisolarCalendar();private static Hashtable gHoliday = new Hashtable();private static Hashtable nHoliday = new Hashtable();private static string[] JQ = { "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至" };private static int[] JQData = { 0, 21208, 43467, 63836, 85337, 107014, 128867, 150921, 173149, 195551, 218072, 240693, 263343, 285989, 308563, 331033, 353350, 375494, 397447, 419210, 440795, 462224, 483532, 504758 };static ChinaDate(){//公历节日gHoliday.Add("0101", "元旦");gHoliday.Add("0214", "情人节");gHoliday.Add("0305", "雷锋日");gHoliday.Add("0308", "妇女节");gHoliday.Add("0312", "植树节");gHoliday.Add("0315", "消费者权益日");gHoliday.Add("0401", "愚人节");gHoliday.Add("0405", "清明节");gHoliday.Add("0501", "劳动节");gHoliday.Add("0504", "青年节");gHoliday.Add("0601", "儿童节");gHoliday.Add("0701", "建党节");gHoliday.Add("0801", "建军节");gHoliday.Add("0910", "教师节");gHoliday.Add("1001", "国庆节");gHoliday.Add("1031", "万圣节");gHoliday.Add("1224", "平安夜");gHoliday.Add("1225", "圣诞节");//农历节日nHoliday.Add("0101", "春节");nHoliday.Add("0115", "元宵节");nHoliday.Add("0505", "端午节");nHoliday.Add("0815", "中秋节");nHoliday.Add("0909", "重阳节");nHoliday.Add("1208", "腊八节");nHoliday.Add("1230", "大年三十");}/// <summary>/// 获取农历/// </summary>/// <param name="dt"></param>/// <returns></returns>public static string GetChinaDate(DateTime dt){if (dt > china.MaxSupportedDateTime || dt < china.MinSupportedDateTime){//日期范围:1901 年 2 月 19 日 - 2101 年 1 月 28 日throw new Exception(string.Format("日期超出范围!必须在{0}到{1}之间!", china.MinSupportedDateTime.ToString("yyyy-MM-dd"), china.MaxSupportedDateTime.ToString("yyyy-MM-dd")));}string str = string.Format("{0} {1}{2}", GetYear(dt), GetMonth(dt), GetDay(dt));string strJQ = GetSolarTerm(dt);if (strJQ != ""){str += " (" + strJQ + ")";}string[] strHoliday = GetHoliday(dt, 0);if (strHoliday != null){str += " " + strHoliday;}string[] strChinaHoliday = GetChinaHoliday(dt, 0);if (strChinaHoliday != null){str += " " + strChinaHoliday;}return str;}/// <summary>/// 获取农历年份/// </summary>/// <param name="dt"></param>/// <returns></returns>public static string GetYear(DateTime dt){int yearIndex = china.GetSexagenaryYear(dt);string yearTG = " 甲乙丙丁戊己庚辛壬癸";string yearDZ = " 子丑寅卯辰巳午未申酉戌亥";string yearSX = " 鼠牛虎兔龙蛇马羊猴鸡狗猪";int year = china.GetYear(dt);int yTG = china.GetCelestialStem(yearIndex);int yDZ = china.GetTerrestrialBranch(yearIndex);string str = string.Format("[{1}]{2}{3}{0}", year, yearSX[yDZ], yearTG[yTG], yearDZ[yDZ]);return str;}/// <summary>/// 得到公历所对应的农历年/// </summary>/// <param name="dt"></param>/// <returns></returns>public static string GetChinaYear(DateTime dt){return china.GetYear(dt).ToString();}/// <summary>/// 获取农历月份/// </summary>/// <param name="dt"></param>/// <returns></returns>public static string GetMonth(DateTime dt){int year = china.GetYear(dt);int iMonth = china.GetMonth(dt);int leapMonth = china.GetLeapMonth(year);bool isLeapMonth = iMonth == leapMonth;if (leapMonth != 0 && iMonth >= leapMonth){iMonth--;}string szText = "正二三四五六七八九十";string strMonth = isLeapMonth ? "闰" : "";if (iMonth <= 10){strMonth = "";strMonth = strMonth + szText.Substring(iMonth - 1, 1);}else if (iMonth == 11){strMonth = "十一";}else{strMonth = "腊";}return strMonth + "月";}/// <summary>/// 获取农历日期/// </summary>/// <param name="dt"></param>/// <returns></returns>public static string GetDay(DateTime dt){int iDay = china.GetDayOfMonth(dt);string szText1 = "初十廿三";string szText2 = "一二三四五六七八九十";string strDay;if (iDay == 20){strDay = "二十";}else if (iDay == 30){strDay = "三十";}else{strDay = szText1.Substring((iDay - 1) / 10, 1);strDay = strDay + szText2.Substring((iDay - 1) % 10, 1);}return strDay;}private static string GetNongLiDay(string str){string ret = string.Empty;ret += ConvertNongliToDigital(str.Substring(0, 1), 0);ret += ConvertNongliToDigital(str.Substring(1, 1), 1);return ret;}private static string GetNongLiMonth(string str){string ret = string.Empty;if (str.Length == 2) //是 十月 还是 十一月{ret += ConvertMonthToDigital(str.Substring(0, 1));ret += ConvertMonthToDigital(str.Substring(1, 1));}else if (str.Length == 3){ret += ConvertMonthToDigital(str.Substring(0, 2));}return ret;}/// <summary>/// 把汉字月转换成对应的数字/// </summary>/// <param name="nonglimonth"></param>/// <returns></returns>private static string ConvertMonthToDigital(string nonglimonth){string ret = string.Empty;switch (nonglimonth){case "一": ret = "1";break;case "二": ret = "2";break;case "三": ret = "3";break;case "四": ret = "4";break;case "五": ret = "5";break;case "六": ret = "6";break;case "七": ret = "7";break;case "八": ret = "8";break;case "九": ret = "9";break;case "十":ret = "10";break;case "十一":ret = "11";break;case "十二":ret = "12";break;case "正":ret = "1";break;case "腊":ret = "12";break;}return ret;}/// <summary>/// 把汉字日转换成对应的数字,first,是用来区别十这个汉字,是在第一个位置还是在别的位置上/// </summary>/// <param name="nongli"></param>/// <param name="first"></param>/// <returns></returns>private static string ConvertNongliToDigital(string nongli, int first){string ret = string.Empty;switch (nongli){case "一": ret = "1";break;case "二": ret = "2";break;case "三": ret = "3";break;case "四": ret = "4";break;case "五": ret = "5";break;case "六": ret = "6";break;case "七": ret = "7";break;case "八": ret = "8";break;case "九": ret = "9";break;case "十":if (first == 1){ret = "0";}else ret = "1";break;case "初": ret = "0";break;case "廿": ret = "2";break;}return ret;}/// <summary>/// 获取节气/// </summary>/// <param name="dt"></param>/// <returns></returns>public static string GetSolarTerm(DateTime dt){DateTime dtBase = new DateTime(1900, 1, 6, 2, 5, 0);DateTime dtNew;double num;int y;string strReturn = "";y = dt.Year;for (int i = 1; i <= 24; i++){num = 525948.76 * (y - 1900) + JQData[i - 1];dtNew = dtBase.AddMinutes(num);if (dtNew.DayOfYear == dt.DayOfYear){strReturn = JQ[i - 1];}}return strReturn;}/// <summary>/// 获取公历节日/// </summary>/// <param name="dt"></param>/// <returns></returns>public static string[] GetHoliday(DateTime dt, int next) //next为0表示当前月,next为1表示下个月{string strReturn = "";object g = null;if (next == 0){g = gHoliday[dt.Month.ToString("00") + dt.Day.ToString("00")];}if (g != null){strReturn = g.ToString();return new string[] { dt.Month.ToString("00") + dt.Day.ToString("00"), g.ToString() };}else{string first = string.Empty;int day = 0;//当前多少号if (next == 0){first = dt.Month.ToString("00");day = dt.Day; //当前多少号}else{dt = dt.AddMonths(next);first = dt.Month.ToString("00");}day++;for (int i = day; i <= 31; i++){object festival = gHoliday[first + i.ToString("00")];if (festival != null){string[] ret = { first + i.ToString("00"), festival.ToString() }; //当前当月的离今天最近的一个节日return ret;}}}return null;}/// <summary>/// 获取农历节日/// </summary>/// <param name="dt"></param>/// <returns></returns>public static string[] GetChinaHoliday(DateTime dt, int next) //next表示是否是下一个月{string strReturn = string.Empty;int year = china.GetYear(dt);int iMonth = china.GetMonth(dt);int leapMonth = china.GetLeapMonth(year);int iDay = china.GetDayOfMonth(dt);if (china.GetDayOfYear(dt) == china.GetDaysInYear(year)){strReturn = "除夕";}else if (leapMonth != iMonth){if (leapMonth != 0 && iMonth >= leapMonth){iMonth--;}object n = nHoliday[iMonth.ToString("00") + iDay.ToString("00")];if (n != null){string[] ret = { iMonth.ToString("00") + iDay.ToString("00"), n.ToString() };return ret;}else //该日期没有节日{if (next != 0){iDay = 0;iMonth += next;}for (int i = iDay; i <= 31; i++){object festival = nHoliday[iMonth.ToString("00") + i.ToString("00")];if (festival != null){string[] ret = { iMonth.ToString("00") + i.ToString("00"), festival.ToString() };return ret;}}}}if (strReturn != string.Empty){return new string[] { "1230", "除夕" };}return null;}/// <summary>/// 把阳历转成农历/// </summary>/// <param name="dt"></param>/// <returns></returns>public static DateTime ConvertToNongLi(DateTime dt){string year = ChinaDate.GetChinaYear(dt);string month = ChinaDate.GetNongLiMonth(ChinaDate.GetMonth(dt));string day = ChinaDate.GetNongLiDay(ChinaDate.GetDay(dt));DateTime dtnongli = DateTime.Parse(year + "-" + month + "-" + day);return dtnongli;}/// <summary>/// 得到节日,没有节日的话,就返回empty/// </summary>/// <param name="dt"></param>/// <returns></returns>public static string GetFestival(DateTime dt){try{string currentfestival = string.Empty;string nonglidate = string.Empty;string gonglidate = string.Empty;int distance = 0;int basemonth = 0;string[] gongli = ChinaDate.GetHoliday(dt, basemonth);//公历节日string[] nongli = ChinaDate.GetChinaHoliday(dt, basemonth);//农历节日bool festival = true; //是否这个月内有节日DateTime dtGongli = dt;DateTime dtNongli = dt;if (gongli == null && nongli == null) //如果同时为空,就取下个月的{basemonth++;gongli = ChinaDate.GetHoliday(dt, basemonth);//公历节日nongli = ChinaDate.GetChinaHoliday(dt, basemonth);//农历节日}//dt = dt.AddMonths(basemonth);if (gongli != null){DateTime riqi = DateTime.Parse(dt.Year.ToString() + "-" + gongli[0].Substring(0, 2) + "-" + gongli[0].Substring(2, 2));dtGongli = ConvertToNongLi(riqi);}if (nongli != null){dtNongli = DateTime.Parse(ChinaDate.GetChinaYear(dt) + "-" + nongli[0].Substring(0, 2) + "-" + nongli[0].Substring(2, 2));}System.Text.StringBuilder today = new System.Text.StringBuilder();//today.Append(DateTime.Now.ToString("yyyy-MM-dd") + " " + DateTime.Now.ToString("ddd", new System.Globalization.CultureInfo("zh-cn")) + " ");if (gongli != null && nongli != null){TimeSpan ts = dtGongli - dtNongli;if (ts.Days < 0)// 公历的节日更近 把两个日期都转换成公历进行比较{currentfestival = gongli[1];gonglidate = gongli[0];TimeSpan tsDay = dtGongli - ConvertToNongLi(dt);distance = tsDay.Days;}else{ts = dtNongli - dtGongli;currentfestival = nongli[1];TimeSpan tsDay = dtNongli - ConvertToNongLi(dt);distance = tsDay.Days;}}else if (gongli != null){currentfestival = gongli[1];DateTime dtfestival = ConvertToNongLi(DateTime.Parse(ChinaDate.GetChinaYear(dt) + "-" + gongli[0].Substring(0, 2) + "-" + gongli[0].Substring(2, 2)));TimeSpan tsDay = dtfestival - ConvertToNongLi(dt);distance = tsDay.Days;}else if (nongli != null){currentfestival = nongli[1];distance = int.Parse(nongli[0].Substring(2, 2)) - ConvertToNongLi(dt).Day;}else festival = false;//today.Append("农历" + ChinaDate.GetMonth(dt) + ChinaDate.GetDay(dt));if (festival){if (distance > 0)today.Append(" 离<font color='red'>" + currentfestival + "</font>还有<font color='red'>" + distance + "</font>天 ");else today.Append(" 今天是 <font color='red'>" + currentfestival + "</font> ");}//else today.Append(" ");return today.ToString();}catch{return string.Empty;}}}
}