C#实现万年历(农历、节气、节日、星座、属相、生肖、闰年等)

C# 万年历 农历 节气 节日 星座 星宿 属相 生肖 闰年月 时辰等,代码如下:
    
    
    
    
using System.Collections.Generic; using System.Text; using System; namespace yangliToyinli { #region ChineseCalendarException /// /// 中国日历异常处理 /// public class ChineseCalendarException : System.Exception { public ChineseCalendarException( string msg) : base (msg) { } } #endregion /// /// 中国农历类 版本V1.0 支持 1900.1.31日起至 2049.12.31日止的数据 /// /// /// 本程序使用数据来源于网上的万年历查询,并综合了一些其它数据 /// public class ChineseCalendar { #region 内部结构 private struct SolarHolidayStruct { public int Month; public int Day; public int Recess; // 假期长度 public string HolidayName; public SolarHolidayStruct( int month, int day, int recess, string name) { Month = month; Day = day; Recess = recess; HolidayName = name; } } private struct LunarHolidayStruct { public int Month; public int Day; public int Recess; public string HolidayName; public LunarHolidayStruct( int month, int day, int recess, string name) { Month = month; Day = day; Recess = recess; HolidayName = name; } } private struct WeekHolidayStruct { public int Month; public int WeekAtMonth; public int WeekDay; public string HolidayName; public WeekHolidayStruct( int month, int weekAtMonth, int weekDay, string name) { Month = month; WeekAtMonth = weekAtMonth; WeekDay = weekDay; HolidayName = name; } } #endregion #region 内部变量 private DateTime _date; private DateTime _datetime; private int _cYear; private int _cMonth; private int _cDay; private bool _cIsLeapMonth; // 当月是否闰月 private bool _cIsLeapYear; // 当年是否有闰月 #endregion #region 基础数据 #region 基本常量 private const int MinYear = 1900 ; private const int MaxYear = 2050 ; private static DateTime MinDay = new DateTime( 1900 , 1 , 30 ); private static DateTime MaxDay = new DateTime( 2049 , 12 , 31 ); private const int GanZhiStartYear = 1864 ; // 干支计算起始年 private static DateTime GanZhiStartDay = new DateTime( 1899 , 12 , 22 ); // 起始日 private const string HZNum = " 零一二三四五六七八九 " ; private const int AnimalStartYear = 1900 ; // 1900年为鼠年 private static DateTime ChineseConstellationReferDay = new DateTime( 2007 , 9 , 13 ); // 28星宿参考值,本日为角 #endregion #region 阴历数据 /// /// 来源于网上的农历数据 /// /// /// 数据结构如下,共使用17位数据 /// 第17位:表示闰月天数,0表示29天 1表示30天 /// 第16位-第5位(共12位)表示12个月,其中第16位表示第一月,如果该月为30天则为1,29天为0 /// 第4位-第1位(共4位)表示闰月是哪个月,如果当年没有闰月,则置0 /// private static int [] LunarDateArray = new int []{ x04BD8, 0x04AE0 , 0x0A570 , 0x054D5 , 0x0D260 , 0x0D950 , 0x16554 , 0x056A0 , 0x09AD0 , 0x055D2 , x04AE0, 0x0A5B6 , 0x0A4D0 , 0x0D250 , 0x1D255 , 0x0B540 , 0x0D6A0 , 0x0ADA2 , 0x095B0 , 0x14977 , x04970, 0x0A4B0 , 0x0B4B5 , 0x06A50 , 0x06D40 , 0x1AB54 , 0x02B60 , 0x09570 , 0x052F2 , 0x04970 , x06566, 0x0D4A0 , 0x0EA50 , 0x06E95 , 0x05AD0 , 0x02B60 , 0x186E3 , 0x092E0 , 0x1C8D7 , 0x0C950 , x0D4A0, 0x1D8A6 , 0x0B550 , 0x056A0 , 0x1A5B4 , 0x025D0 , 0x092D0 , 0x0D2B2 , 0x0A950 , 0x0B557 , x06CA0, 0x0B550 , 0x15355 , 0x04DA0 , 0x0A5B0 , 0x14573 , 0x052B0 , 0x0A9A8 , 0x0E950 , 0x06AA0 , x0AEA6, 0x0AB50 , 0x04B60 , 0x0AAE4 , 0x0A570 , 0x05260 , 0x0F263 , 0x0D950 , 0x05B57 , 0x056A0 , x096D0, 0x04DD5 , 0x04AD0 , 0x0A4D0 , 0x0D4D4 , 0x0D250 , 0x0D558 , 0x0B540 , 0x0B6A0 , 0x195A6 , x095B0, 0x049B0 , 0x0A974 , 0x0A4B0 , 0x0B27A , 0x06A50 , 0x06D40 , 0x0AF46 , 0x0AB60 , 0x09570 , x04AF5, 0x04970 , 0x064B0 , 0x074A3 , 0x0EA50 , 0x06B58 , 0x055C0 , 0x0AB60 , 0x096D5 , 0x092E0 , x0C960, 0x0D954 , 0x0D4A0 , 0x0DA50 , 0x07552 , 0x056A0 , 0x0ABB7 , 0x025D0 , 0x092D0 , 0x0CAB5 , x0A950, 0x0B4A0 , 0x0BAA4 , 0x0AD50 , 0x055D9 , 0x04BA0 , 0x0A5B0 , 0x15176 , 0x052B0 , 0x0A930 , x07954, 0x06AA0 , 0x0AD50 , 0x05B52 , 0x04B60 , 0x0A6E6 , 0x0A4E0 , 0x0D260 , 0x0EA65 , 0x0D530 , x05AA0, 0x076A3 , 0x096D0 , 0x04BD7 , 0x04AD0 , 0x0A4D0 , 0x1D0B6 , 0x0D250 , 0x0D520 , 0x0DD45 , x0B5A0, 0x056D0 , 0x055B2 , 0x049B0 , 0x0A577 , 0x0A4B0 , 0x0AA50 , 0x1B255 , 0x06D20 , 0x0ADA0 , x14B63 }; #endregion #region 星座名称 private static string [] _constellationName = { " 白羊座 " , " 金牛座 " , " 双子座 " , " 巨蟹座 " , " 狮子座 " , " 处女座 " , " 天秤座 " , " 天蝎座 " , " 射手座 " , " 摩羯座 " , " 水瓶座 " , " 双鱼座 " }; #endregion #region 二十四节气 private static string [] _lunarHolidayName = { " 小寒 " , " 大寒 " , " 立春 " , " 雨水 " , " 惊蛰 " , " 春分 " , " 清明 " , " 谷雨 " , " 立夏 " , " 小满 " , " 芒种 " , " 夏至 " , " 小暑 " , " 大暑 " , " 立秋 " , " 处暑 " , " 白露 " , " 秋分 " , " 寒露 " , " 霜降 " , " 立冬 " , " 小雪 " , " 大雪 " , " 冬至 " }; #endregion #region 二十八星宿 private static string [] _chineseConstellationName = { // 四 五 六 日 一 二 三 " 角木蛟 " , " 亢金龙 " , " 女土蝠 " , " 房日兔 " , " 心月狐 " , " 尾火虎 " , " 箕水豹 " , " 斗木獬 " , " 牛金牛 " , " 氐土貉 " , " 虚日鼠 " , " 危月燕 " , " 室火猪 " , " 壁水獝 " , " 奎木狼 " , " 娄金狗 " , " 胃土彘 " , " 昴日鸡 " , " 毕月乌 " , " 觜火猴 " , " 参水猿 " , " 井木犴 " , " 鬼金羊 " , " 柳土獐 " , " 星日马 " , " 张月鹿 " , " 翼火蛇 " , " 轸水蚓 " }; #endregion #region 节气数据 private static string [] SolarTerm = new string [] { " 小寒 " , " 大寒 " , " 立春 " , " 雨水 " , " 惊蛰 " , " 春分 " , " 清明 " , " 谷雨 " , " 立夏 " , " 小满 " , " 芒种 " , " 夏至 " , " 小暑 " , " 大暑 " , " 立秋 " , " 处暑 " , " 白露 " , " 秋分 " , " 寒露 " , " 霜降 " , " 立冬 " , " 小雪 " , " 大雪 " , " 冬至 " }; private static int [] sTermInfo = new int [] { 0 , 21208 , 42467 , 63836 , 85337 , 107014 , 128867 , 150921 , 173149 , 195551 , 218072 , 240693 , 263343 , 285989 , 308563 , 331033 , 353350 , 375494 , 397447 , 419210 , 440795 , 462224 , 483532 , 504758 }; #endregion #region 农历相关数据 private static string ganStr = " 甲乙丙丁戊己庚辛壬癸 " ; private static string zhiStr = " 子丑寅卯辰巳午未申酉戌亥 " ; private static string animalStr = " 鼠牛虎兔龙蛇马羊猴鸡狗猪 " ; private static string nStr1 = " 日一二三四五六七八九 " ; private static string nStr2 = " 初十廿卅 " ; private static string [] _monthString = { " 出错 " , " 正月 " , " 二月 " , " 三月 " , " 四月 " , " 五月 " , " 六月 " , " 七月 " , " 八月 " , " 九月 " , " 十月 " , " 十一月 " , " 腊月 " }; #endregion #region 按公历计算的节日 private static SolarHolidayStruct[] sHolidayInfo = new SolarHolidayStruct[]{ new SolarHolidayStruct( 1 , 1 , 1 , " 元旦 " ), new SolarHolidayStruct( 2 , 2 , 0 , " 世界湿地日 " ), new SolarHolidayStruct( 2 , 10 , 0 , " 国际气象节 " ), new SolarHolidayStruct( 2 , 14 , 0 , " 情人节 " ), new SolarHolidayStruct( 3 , 1 , 0 , " 国际海豹日 " ), new SolarHolidayStruct( 3 , 5 , 0 , " 学雷锋纪念日 " ), new SolarHolidayStruct( 3 , 8 , 0 , " 妇女节 " ), new SolarHolidayStruct( 3 , 12 , 0 , " 植树节 孙中山逝世纪念日 " ), new SolarHolidayStruct( 3 , 14 , 0 , " 国际警察日 " ), new SolarHolidayStruct( 3 , 15 , 0 , " 消费者权益日 " ), new SolarHolidayStruct( 3 , 17 , 0 , " 中国国医节 国际航海日 " ), new SolarHolidayStruct( 3 , 21 , 0 , " 世界森林日 消除种族歧视国际日 世界儿歌日 " ), new SolarHolidayStruct( 3 , 22 , 0 , " 世界水日 " ), new SolarHolidayStruct( 3 , 24 , 0 , " 世界防治结核病日 " ), new SolarHolidayStruct( 4 , 1 , 0 , " 愚人节 " ), new SolarHolidayStruct( 4 , 7 , 0 , " 世界卫生日 " ), new SolarHolidayStruct( 4 , 22 , 0 , " 世界地球日 " ), new SolarHolidayStruct( 5 , 1 , 1 , " 劳动节 " ), new SolarHolidayStruct( 5 , 2 , 1 , " 劳动节假日 " ), new SolarHolidayStruct( 5 , 3 , 1 , " 劳动节假日 " ), new SolarHolidayStruct( 5 , 4 , 0 , " 青年节 " ), new SolarHolidayStruct( 5 , 8 , 0 , " 世界红十字日 " ), new SolarHolidayStruct( 5 , 12 , 0 , " 国际护士节 " ), new SolarHolidayStruct( 5 , 31 , 0 , " 世界无烟日 " ), new SolarHolidayStruct( 6 , 1 , 0 , " 国际儿童节 " ), new SolarHolidayStruct( 6 , 5 , 0 , " 世界环境保护日 " ), new SolarHolidayStruct( 6 , 26 , 0 , " 国际禁毒日 " ), new SolarHolidayStruct( 7 , 1 , 0 , " 建党节 香港回归纪念 世界建筑日 " ), new SolarHolidayStruct( 7 , 11 , 0 , " 世界人口日 " ), new SolarHolidayStruct( 8 , 1 , 0 , " 建军节 " ), new SolarHolidayStruct( 8 , 8 , 0 , " 中国男子节 父亲节 " ), new SolarHolidayStruct( 8 , 15 , 0 , " 抗日战争胜利纪念 " ), new SolarHolidayStruct( 9 , 9 , 0 , " 逝世纪念 " ), new SolarHolidayStruct( 9 , 10 , 0 , " 教师节 " ), new SolarHolidayStruct( 9 , 18 , 0 , " 九·一八事变纪念日 " ), new SolarHolidayStruct( 9 , 20 , 0 , " 国际爱牙日 " ), new SolarHolidayStruct( 9 , 27 , 0 , " 世界旅游日 " ), new SolarHolidayStruct( 9 , 28 , 0 , " 孔子诞辰 " ), new SolarHolidayStruct( 10 , 1 , 1 , " 国庆节 国际音乐日 " ), new SolarHolidayStruct( 10 , 2 , 1 , " 国庆节假日 " ), new SolarHolidayStruct( 10 , 3 , 1 , " 国庆节假日 " ), new SolarHolidayStruct( 10 , 6 , 0 , " 老人节 " ), new SolarHolidayStruct( 10 , 24 , 0 , " 联合国日 " ), new SolarHolidayStruct( 11 , 10 , 0 , " 世界青年节 " ), new SolarHolidayStruct( 11 , 12 , 0 , " 孙中山诞辰纪念 " ), new SolarHolidayStruct( 12 , 1 , 0 , " 世界艾滋病日 " ), new SolarHolidayStruct( 12 , 3 , 0 , " 世界残疾人日 " ), new SolarHolidayStruct( 12 , 20 , 0 , " 澳门回归纪念 " ), new SolarHolidayStruct( 12 , 24 , 0 , " 平安夜 " ), new SolarHolidayStruct( 12 , 25 , 0 , " 圣诞节 " ), new SolarHolidayStruct( 12 , 26 , 0 , " 诞辰纪念 " ) }; #endregion #region 按农历计算的节日 private static LunarHolidayStruct[] lHolidayInfo = new LunarHolidayStruct[]{ new LunarHolidayStruct( 1 , 1 , 1 , " 春节 " ), new LunarHolidayStruct( 1 , 15 , 0 , " 元宵节 " ), new LunarHolidayStruct( 5 , 5 , 0 , " 端午节 " ), new LunarHolidayStruct( 7 , 7 , 0 , " 七夕情人节 " ), new LunarHolidayStruct( 7 , 15 , 0 , " 中元节 盂兰盆节 " ), new LunarHolidayStruct( 8 , 15 , 0 , " 中秋节 " ), new LunarHolidayStruct( 9 , 9 , 0 , " 重阳节 " ), new LunarHolidayStruct( 12 , 8 , 0 , " 腊八节 " ), new LunarHolidayStruct( 12 , 23 , 0 , " 北方小年(扫房) " ), new LunarHolidayStruct( 12 , 24 , 0 , " 南方小年(掸尘) " ), // new LunarHolidayStruct(12, 30, 0, "除夕") // 注意除夕需要其它方法进行计算 }; #endregion #region 按某月第几个星期几 private static WeekHolidayStruct[] wHolidayInfo = new WeekHolidayStruct[]{ new WeekHolidayStruct( 5 , 2 , 1 , " 母亲节 " ), new WeekHolidayStruct( 5 , 3 , 1 , " 全国助残日 " ), new WeekHolidayStruct( 6 , 3 , 1 , " 父亲节 " ), new WeekHolidayStruct( 9 , 3 , 3 , " 国际和平日 " ), new WeekHolidayStruct( 9 , 4 , 1 , " 国际聋人节 " ), new WeekHolidayStruct( 10 , 1 , 2 , " 国际住房日 " ), new WeekHolidayStruct( 10 , 1 , 4 , " 国际减轻自然灾害日 " ), new WeekHolidayStruct( 11 , 4 , 5 , " 感恩节 " ) }; #endregion #endregion #region 构造函数 #region ChinaCalendar <公历日期初始化> /// /// 用一个标准的公历日期来初使化 /// /// public ChineseCalendar(DateTime dt) { int i; int leap; int temp; int offset; CheckDateLimit(dt); _date = dt.Date; _datetime = dt; // 农历日期计算部分 leap = 0 ; temp = 0 ; TimeSpan ts = _date - ChineseCalendar.MinDay; // 计算两天的基本差距 offset = ts.Days; for (i = MinYear; i <= MaxYear; i ++ ) { temp = GetChineseYearDays(i); // 求当年农历年天数 if (offset - temp < 1 ) break ; else { offset = offset - temp; } } _cYear = i; leap = GetChineseLeapMonth(_cYear); // 计算该年闰哪个月 // 设定当年是否有闰月 if (leap > 0 ) { _cIsLeapYear = true ; } else { _cIsLeapYear = false ; } _cIsLeapMonth = false ; for (i = 1 ; i <= 12 ; i ++ ) { // 闰月 if ((leap > 0 ) && (i == leap + 1 ) && (_cIsLeapMonth == false )) { _cIsLeapMonth = true ; i = i - 1 ; temp = GetChineseLeapMonthDays(_cYear); // 计算闰月天数 } else { _cIsLeapMonth = false ; temp = GetChineseMonthDays(_cYear, i); // 计算非闰月天数 } offset = offset - temp; if (offset <= 0 ) break ; } offset = offset + temp; _cMonth = i; _cDay = offset; } #endregion #region ChinaCalendar <农历日期初始化> /// /// 用农历的日期来初使化 /// /// 农历年 /// 农历月 /// 农历日 /// 闰月标志 public ChineseCalendar( int cy, int cm, int cd, bool leapMonthFlag) { int i, leap, Temp, offset; CheckChineseDateLimit(cy, cm, cd, leapMonthFlag); _cYear = cy; _cMonth = cm; _cDay = cd; offset = 0 ; for (i = MinYear; i < cy; i ++ ) { Temp = GetChineseYearDays(i); // 求当年农历年天数 offset = offset + Temp; } leap = GetChineseLeapMonth(cy); // 计算该年应该闰哪个月 if (leap != 0 ) { this ._cIsLeapYear = true ; } else { this ._cIsLeapYear = false ; } if (cm != leap) { _cIsLeapMonth = false ; // 当前日期并非闰月 } else { _cIsLeapMonth = leapMonthFlag; // 使用用户输入的是否闰月月份 } if ((_cIsLeapYear == false ) || // 当年没有闰月 (cm < leap)) // 计算月份小于闰月 { #region ... for (i = 1 ; i < cm; i ++ ) { Temp = GetChineseMonthDays(cy, i); // 计算非闰月天数 offset = offset + Temp; } // 检查日期是否大于最大天 if (cd > GetChineseMonthDays(cy, cm)) { throw new ChineseCalendarException( " 不合法的农历日期 " ); } offset = offset + cd; // 加上当月的天数 #endregion } else // 是闰年,且计算月份大于或等于闰月 { #region ... for (i = 1 ; i < cm; i ++ ) { Temp = GetChineseMonthDays(cy, i); // 计算非闰月天数 offset = offset + Temp; } if (cm > leap) // 计算月大于闰月 { Temp = GetChineseLeapMonthDays(cy); // 计算闰月天数 offset = offset + Temp; // 加上闰月天数 if (cd > GetChineseMonthDays(cy, cm)) { throw new ChineseCalendarException( " 不合法的农历日期 " ); } offset = offset + cd; } else // 计算月等于闰月 { // 如果需要计算的是闰月,则应首先加上与闰月对应的普通月的天数 if ( this ._cIsLeapMonth == true ) // 计算月为闰月 { Temp = GetChineseMonthDays(cy, cm); // 计算非闰月天数 offset = offset + Temp; } if (cd > GetChineseLeapMonthDays(cy)) { throw new ChineseCalendarException( " 不合法的农历日期 " ); } offset = offset + cd; } #endregion } _date = MinDay.AddDays(offset); } #endregion #endregion #region 私有函数 #region GetChineseMonthDays // 传回农历 y年m月的总天数 private int GetChineseMonthDays( int year, int month) { if (BitTest32((LunarDateArray[year - MinYear] & 0x0000FFFF ), ( 16 - month))) { return 30 ; } else { return 29 ; } } #endregion #region GetChineseLeapMonth // 传回农历 y年闰哪个月 1-12 , 没闰传回 0 private int GetChineseLeapMonth( int year) { return LunarDateArray[year - MinYear] & 0xF ; } #endregion #region GetChineseLeapMonthDays // 传回农历 y年闰月的天数 private int GetChineseLeapMonthDays( int year) { if (GetChineseLeapMonth(year) != 0 ) { if ((LunarDateArray[year - MinYear] & 0x10000 ) != 0 ) { return 30 ; } else { return 29 ; } } else { return 0 ; } } #endregion #region GetChineseYearDays /// /// 取农历年一年的天数 /// /// /// private int GetChineseYearDays( int year) { int i, f, sumDay, info; sumDay = 348 ; // 29天 X 12个月 i = 0x8000 ; info = LunarDateArray[year - MinYear] & 0x0FFFF ; // 计算12个月中有多少天为30天 for ( int m = 0 ; m < 12 ; m ++ ) { f = info & i; if (f != 0 ) { sumDay ++ ; } i = i >> 1 ; } return sumDay + GetChineseLeapMonthDays(year); } #endregion #region GetChineseHour /// /// 获得当前时间的时辰 /// /// /// /// private string GetChineseHour(DateTime dt) { int _hour, _minute, offset, i; int indexGan; string ganHour, zhiHour; string tmpGan; // 计算时辰的地支 _hour = dt.Hour; // 获得当前时间小时 _minute = dt.Minute; // 获得当前时间分钟 if (_minute != 0 ) _hour += 1 ; offset = _hour / 2 ; if (offset >= 12 ) offset = 0 ; // zhiHour = zhiStr[offset].ToString(); // 计算天干 TimeSpan ts = this ._date - GanZhiStartDay; i = ts.Days % 60 ; indexGan = ((i % 10 + 1 ) * 2 - 1 ) % 10 - 1 ; // ganStr[i % 10] 为日的天干,(n*2-1) %10得出地支对应,n从1开始 tmpGan = ganStr.Substring(indexGan) + ganStr.Substring( 0 , indexGan + 2 ); // 凑齐12位 // ganHour = ganStr[((i % 10 + 1) * 2 - 1) % 10 - 1].ToString(); return tmpGan[offset].ToString() + zhiStr[offset].ToString(); } #endregion #region CheckDateLimit /// /// 检查公历日期是否符合要求 /// /// private void CheckDateLimit(DateTime dt) { if ((dt < MinDay) || (dt > MaxDay)) { throw new ChineseCalendarException( " 超出可转换的日期 " ); } } #endregion #region CheckChineseDateLimit /// /// 检查农历日期是否合理 /// /// /// /// /// private void CheckChineseDateLimit( int year, int month, int day, bool leapMonth) { if ((year < MinYear) || (year > MaxYear)) { throw new ChineseCalendarException( " 非法农历日期 " ); } if ((month < 1 ) || (month > 12 )) { throw new ChineseCalendarException( " 非法农历日期 " ); } if ((day < 1 ) || (day > 30 )) // 中国的月最多30天 { throw new ChineseCalendarException( " 非法农历日期 " ); } int leap = GetChineseLeapMonth(year); // 计算该年应该闰哪个月 if ((leapMonth == true ) && (month != leap)) { throw new ChineseCalendarException( " 非法农历日期 " ); } } #endregion #region ConvertNumToChineseNum /// /// 将0-9转成汉字形式 /// /// /// private string ConvertNumToChineseNum( char n) { if ((n < ' 0 ' ) || (n > ' 9 ' )) return "" ; switch (n) { case ' 0 ' : return HZNum[ 0 ].ToString(); case ' 1 ' : return HZNum[ 1 ].ToString(); case ' 2 ' : return HZNum[ 2 ].ToString(); case ' 3 ' : return HZNum[ 3 ].ToString(); case ' 4 ' : return HZNum[ 4 ].ToString(); case ' 5 ' : return HZNum[ 5 ].ToString(); case ' 6 ' : return HZNum[ 6 ].ToString(); case ' 7 ' : return HZNum[ 7 ].ToString(); case ' 8 ' : return HZNum[ 8 ].ToString(); case ' 9 ' : return HZNum[ 9 ].ToString(); default : return "" ; } } #endregion #region BitTest32 /// /// 测试某位是否为真 /// /// /// /// private bool BitTest32( int num, int bitpostion) { if ((bitpostion > 31 ) || (bitpostion < 0 )) throw new Exception( " Error Param: bitpostion[0-31]: " + bitpostion.ToString()); int bit = 1 << bitpostion; if ((num & bit) == 0 ) { return false ; } else { return true ; } } #endregion #region ConvertDayOfWeek /// /// 将星期几转成数字表示 /// /// /// private int ConvertDayOfWeek(DayOfWeek dayOfWeek) { switch (dayOfWeek) { case DayOfWeek.Sunday: return 1 ; case DayOfWeek.Monday: return 2 ; case DayOfWeek.Tuesday: return 3 ; case DayOfWeek.Wednesday: return 4 ; case DayOfWeek.Thursday: return 5 ; case DayOfWeek.Friday: return 6 ; case DayOfWeek.Saturday: return 7 ; default : return 0 ; } } #endregion #region CompareWeekDayHoliday /// /// 比较当天是不是指定的第周几 /// /// /// /// /// /// private bool CompareWeekDayHoliday(DateTime date, int month, int week, int day) { bool ret = false ; if (date.Month == month) // 月份相同 { if (ConvertDayOfWeek(date.DayOfWeek) == day) // 星期几相同 { DateTime firstDay = new DateTime(date.Year, date.Month, 1 ); // 生成当月第一天 int i = ConvertDayOfWeek(firstDay.DayOfWeek); int firWeekDays = 7 - ConvertDayOfWeek(firstDay.DayOfWeek) + 1 ; // 计算第一周剩余天数 if (i > day) { if ((week - 1 ) * 7 + day + firWeekDays == date.Day) { ret = true ; } } else { if (day + firWeekDays + (week - 2 ) * 7 == date.Day) { ret = true ; } } } } return ret; } #endregion #endregion #region 属性 #region 节日 #region ChineseCalendarHoliday /// /// 计算中国农历节日 /// public string ChineseCalendarHoliday { get { string tempStr = "" ; if ( this ._cIsLeapMonth == false ) // 闰月不计算节日 { foreach (LunarHolidayStruct lh in lHolidayInfo) { if ((lh.Month == this ._cMonth) && (lh.Day == this ._cDay)) { tempStr = lh.HolidayName; break ; } } // 对除夕进行特别处理 if ( this ._cMonth == 12 ) { int i = GetChineseMonthDays( this ._cYear, 12 ); // 计算当年农历12月的总天数 if ( this ._cDay == i) // 如果为最后一天 { tempStr = " 除夕 " ; } } } return tempStr; } } #endregion #region WeekDayHoliday /// /// 按某月第几周第几日计算的节日 /// public string WeekDayHoliday { get { string tempStr = "" ; foreach (WeekHolidayStruct wh in wHolidayInfo) { if (CompareWeekDayHoliday(_date, wh.Month, wh.WeekAtMonth, wh.WeekDay)) { tempStr = wh.HolidayName; break ; } } return tempStr; } } #endregion #region DateHoliday /// /// 按公历日计算的节日 /// public string DateHoliday { get { string tempStr = "" ; foreach (SolarHolidayStruct sh in sHolidayInfo) { if ((sh.Month == _date.Month) && (sh.Day == _date.Day)) { tempStr = sh.HolidayName; break ; } } return tempStr; } } #endregion #endregion #region 公历日期 #region Date /// /// 取对应的公历日期 /// public DateTime Date { get { return _date; } set { _date = value; } } #endregion #region WeekDay /// /// 取星期几 /// public DayOfWeek WeekDay { get { return _date.DayOfWeek; } } #endregion #region WeekDayStr /// /// 周几的字符 /// public string WeekDayStr { get { switch (_date.DayOfWeek) { case DayOfWeek.Sunday: return " 星期日 " ; case DayOfWeek.Monday: return " 星期一 " ; case DayOfWeek.Tuesday: return " 星期二 " ; case DayOfWeek.Wednesday: return " 星期三 " ; case DayOfWeek.Thursday: return " 星期四 " ; case DayOfWeek.Friday: return " 星期五 " ; default : return " 星期六 " ; } } } #endregion #region DateString /// /// 公历日期中文表示法 如一九九七年七月一日 /// public string DateString { get { return " 公元 " + this ._date.ToLongDateString(); } } #endregion #region IsLeapYear /// /// 当前是否公历闰年 /// public bool IsLeapYear { get { return DateTime.IsLeapYear( this ._date.Year); } } #endregion #region ChineseConstellation /// /// 28星宿计算 /// public string ChineseConstellation { get { int offset = 0 ; int modStarDay = 0 ; TimeSpan ts = this ._date - ChineseConstellationReferDay; offset = ts.Days; modStarDay = offset % 28 ; return (modStarDay >= 0 ? _chineseConstellationName[modStarDay] : _chineseConstellationName[ 27 + modStarDay]); } } #endregion #region ChineseHour /// /// 时辰 /// public string ChineseHour { get { return GetChineseHour(_datetime); } } #endregion #endregion #region 农历日期 #region IsChineseLeapMonth /// /// 是否闰月 /// public bool IsChineseLeapMonth { get { return this ._cIsLeapMonth; } } #endregion #region IsChineseLeapYear /// /// 当年是否有闰月 /// public bool IsChineseLeapYear { get { return this ._cIsLeapYear; } } #endregion #region ChineseDay /// /// 农历日 /// public int ChineseDay { get { return this ._cDay; } } #endregion #region ChineseDayString /// /// 农历日中文表示 /// public string ChineseDayString { get { switch ( this ._cDay) { case 0 : return "" ; case 10 : return " 初十 " ; case 20 : return " 二十 " ; case 30 : return " 三十 " ; default : return nStr2[( int )(_cDay / 10 )].ToString() + nStr1[_cDay % 10 ].ToString(); } } } #endregion #region ChineseMonth /// /// 农历的月份 /// public int ChineseMonth { get { return this ._cMonth; } } #endregion #region ChineseMonthString /// /// 农历月份字符串 /// public string ChineseMonthString { get { return _monthString[ this ._cMonth]; } } #endregion #region ChineseYear /// /// 取农历年份 /// public int ChineseYear { get { return this ._cYear; } } #endregion #region ChineseYearString /// /// 取农历年字符串如,一九九七年 /// public string ChineseYearString { get { string tempStr = "" ; string num = this ._cYear.ToString(); for ( int i = 0 ; i < 4 ; i ++ ) { tempStr += ConvertNumToChineseNum(num[i]); } return tempStr + " " ; } } #endregion #region ChineseDateString /// /// 取农历日期表示法:农历一九九七年正月初五 /// public string ChineseDateString { get { if ( this ._cIsLeapMonth == true ) { return " 农历 " + ChineseYearString + " " + ChineseMonthString + ChineseDayString; } else { return " 农历 " + ChineseYearString + ChineseMonthString + ChineseDayString; } } } #endregion #region ChineseTwentyFourDay /// /// 定气法计算二十四节气,二十四节气是按地球公转来计算的,并非是阴历计算的 /// /// /// 节气的定法有两种。古代历法采用的称为"恒气",即按时间把一年等分为24份, /// 每一节气平均得15天有余,所以又称"平气"。现代农历采用的称为"定气",即 /// 按地球在轨道上的位置为标准,一周360°,两节气之间相隔15°。由于冬至时地 /// 球位于近日点附近,运动速度较快,因而太阳在黄道上移动15°的时间不到15天。 /// 夏至前后的情况正好相反,太阳在黄道上移动较慢,一个节气达16天之多。采用 /// 定气时可以保证春、秋两分必然在昼夜平分的那两天。 /// public string ChineseTwentyFourDay { get { DateTime baseDateAndTime = new DateTime( 1900 , 1 , 6 , 2 , 5 , 0 ); // #1/6/1900 2:05:00 AM# DateTime newDate; double num; int y; string tempStr = "" ; y = this ._date.Year; for ( int i = 1 ; i <= 24 ; i ++ ) { num = 525948.76 * (y - 1900 ) + sTermInfo[i - 1 ]; newDate = baseDateAndTime.AddMinutes(num); // 按分钟计算 if (newDate.DayOfYear == _date.DayOfYear) { tempStr = SolarTerm[i - 1 ]; break ; } } return tempStr; } } // 当前日期前一个最近节气 public string ChineseTwentyFourPrevDay { get { DateTime baseDateAndTime = new DateTime( 1900 , 1 , 6 , 2 , 5 , 0 ); // #1/6/1900 2:05:00 AM# DateTime newDate; double num; int y; string tempStr = "" ; y = this ._date.Year; for ( int i = 24 ; i >= 1 ; i -- ) { num = 525948.76 * (y - 1900 ) + sTermInfo[i - 1 ]; newDate = baseDateAndTime.AddMinutes(num); // 按分钟计算 if (newDate.DayOfYear < _date.DayOfYear) { tempStr = string .Format( " {0}[{1}] " , SolarTerm[i - 1 ], newDate.ToString( " yyyy-MM-dd " )); break ; } } return tempStr; } } // 当前日期后一个最近节气 public string ChineseTwentyFourNextDay { get { DateTime baseDateAndTime = new DateTime( 1900 , 1 , 6 , 2 , 5 , 0 ); // #1/6/1900 2:05:00 AM# DateTime newDate; double num; int y; string tempStr = "" ; y = this ._date.Year; for ( int i = 1 ; i <= 24 ; i ++ ) { num = 525948.76 * (y - 1900 ) + sTermInfo[i - 1 ]; newDate = baseDateAndTime.AddMinutes(num); // 按分钟计算 if (newDate.DayOfYear > _date.DayOfYear) { tempStr = string .Format( " {0}[{1}] " , SolarTerm[i - 1 ], newDate.ToString( " yyyy-MM-dd " )); break ; } } return tempStr; } } #endregion #endregion #region 星座 #region Constellation /// /// 计算指定日期的星座序号 /// /// public string Constellation { get { int index = 0 ; int y, m, d; y = _date.Year; m = _date.Month; d = _date.Day; y = m * 100 + d; if (((y >= 321 ) && (y <= 419 ))) { index = 0 ; } else if ((y >= 420 ) && (y <= 520 )) { index = 1 ; } else if ((y >= 521 ) && (y <= 620 )) { index = 2 ; } else if ((y >= 621 ) && (y <= 722 )) { index = 3 ; } else if ((y >= 723 ) && (y <= 822 )) { index = 4 ; } else if ((y >= 823 ) && (y <= 922 )) { index = 5 ; } else if ((y >= 923 ) && (y <= 1022 )) { index = 6 ; } else if ((y >= 1023 ) && (y <= 1121 )) { index = 7 ; } else if ((y >= 1122 ) && (y <= 1221 )) { index = 8 ; } else if ((y >= 1222 ) || (y <= 119 )) { index = 9 ; } else if ((y >= 120 ) && (y <= 218 )) { index = 10 ; } else if ((y >= 219 ) && (y <= 320 )) { index = 11 ; } else { index = 0 ; } return _constellationName[index]; } } #endregion #endregion #region 属相 #region Animal /// /// 计算属相的索引,注意虽然属相是以农历年来区别的,但是目前在实际使用中是按公历来计算的 /// 鼠年为1,其它类推 /// public int Animal { get { int offset = _date.Year - AnimalStartYear; return (offset % 12 ) + 1 ; } } #endregion #region AnimalString /// /// 取属相字符串 /// public string AnimalString { get { int offset = _date.Year - AnimalStartYear; // 阳历计算 // int offset = this._cYear - AnimalStartYear; 农历计算 return animalStr[offset % 12 ].ToString(); } } #endregion #endregion #region 天干地支 #region GanZhiYearString /// /// 取农历年的干支表示法如 乙丑年 /// public string GanZhiYearString { get { string tempStr; int i = ( this ._cYear - GanZhiStartYear) % 60 ; // 计算干支 tempStr = ganStr[i % 10 ].ToString() + zhiStr[i % 12 ].ToString() + " " ; return tempStr; } } #endregion #region GanZhiMonthString /// /// 取干支的月表示字符串,注意农历的闰月不记干支 /// public string GanZhiMonthString { get { // 每个月的地支总是固定的,而且总是从寅月开始 int zhiIndex; string zhi; if ( this ._cMonth > 10 ) { zhiIndex = this ._cMonth - 10 ; } else { zhiIndex = this ._cMonth + 2 ; } zhi = zhiStr[zhiIndex - 1 ].ToString(); // 根据当年的干支年的干来计算月干的第一个 int ganIndex = 1 ; string gan; int i = ( this ._cYear - GanZhiStartYear) % 60 ; // 计算干支 switch (i % 10 ) { #region ... case 0 : // ganIndex = 3 ; break ; case 1 : // ganIndex = 5 ; break ; case 2 : // ganIndex = 7 ; break ; case 3 : // ganIndex = 9 ; break ; case 4 : // ganIndex = 1 ; break ; case 5 : // ganIndex = 3 ; break ; case 6 : // ganIndex = 5 ; break ; case 7 : // ganIndex = 7 ; break ; case 8 : // ganIndex = 9 ; break ; case 9 : // ganIndex = 1 ; break ; #endregion } gan = ganStr[(ganIndex + this ._cMonth - 2 ) % 10 ].ToString(); return gan + zhi + " " ; } } #endregion #region GanZhiDayString /// /// 取干支日表示法 /// public string GanZhiDayString { get { int i, offset; TimeSpan ts = this ._date - GanZhiStartDay; offset = ts.Days; i = offset % 60 ; return ganStr[i % 10 ].ToString() + zhiStr[i % 12 ].ToString() + " " ; } } #endregion #region GanZhiDateString /// /// 取当前日期的干支表示法如 甲子年乙丑月丙庚日 /// public string GanZhiDateString { get { return GanZhiYearString + GanZhiMonthString + GanZhiDayString; } } #endregion #endregion #endregion #region 方法 #region NextDay /// /// 取下一天 /// /// public ChineseCalendar NextDay() { DateTime nextDay = _date.AddDays( 1 ); return new ChineseCalendar(nextDay); } #endregion #region PervDay /// /// 取前一天 /// /// public ChineseCalendar PervDay() { DateTime pervDay = _date.AddDays( - 1 ); return new ChineseCalendar(pervDay); } #endregion #endregion } }
调用:
    
    
    
    
DateTime dt = DateTime.Now; ChineseCalendar cc = new ChineseCalendar(dt); Console.WriteLine( " 阳历: " + cc.DateString); Console.WriteLine( " 属相: " + cc.AnimalString); Console.WriteLine( " 农历: " + cc.ChineseDateString); Console.WriteLine( " 时辰: " + cc.ChineseHour); Console.WriteLine( " 节气: " + cc.ChineseTwentyFourDay); Console.WriteLine( " 节日: " + cc.DateHoliday); Console.WriteLine( " 前一个节气: " + cc.ChineseTwentyFourPrevDay); Console.WriteLine( " 后一个节气: " + cc.ChineseTwentyFourNextDay); Console.WriteLine( " 干支: " + cc.GanZhiDateString); Console.WriteLine( " 星期: " + cc.WeekDayStr); Console.WriteLine( " 星宿: " + cc.ChineseConstellation); Console.WriteLine( " 星座: " + cc.Constellation);
结果:
    
    
    
    
阳历:公元2013年1月27日 属相:蛇 农历:农历二零一二年腊月十六 时辰:庚申 节气: 节日: 前一个节气:大寒[2013-01-20] 后一个节气:立春[2013-02-03] 干支:壬辰年癸丑月癸巳日 星期:星期日 星宿:房日兔 星座:水瓶座
   
   
   
   

你可能感兴趣的:(C#实现万年历(农历、节气、节日、星座、属相、生肖、闰年等))