c#版公曆轉農曆

using System;

namespace LjTools
{
	/// <summary>
	/// 公曆轉農曆算法
	/// </summary>
	public class ChinaDate 
	{
		 private static long[] lunarInfo = new long[] { 0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554,
															   0x056a0, 0x09ad0, 0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0,
															   0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566,
															   0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550,
															   0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0,
															   0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263,
															   0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0,
															   0x195a6, 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, 0x04af5,
															   0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960, 0x0d954, 0x0d4a0,
															   0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9,
															   0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0,
															   0x0d260, 0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520,
															   0x0dd45, 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0 };

		 private static int[] year20 = new int[] { 1, 4, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1 };

		 private static int[] year19 = new int[] { 0, 3, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 };

		 private static int[] year2000 = new int[] { 0, 3, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1 };

		private  static String[] nStr1 = new String[] { "", "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一",
															  "十二" };

		private  static String[] Gan = new String[] { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" };

		private  static String[] Zhi = new String[] { "子", "醜", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" };

		private  static String[] Animals = new String[] { "鼠", "牛", "虎", "兔", "龍", "蛇", "馬", "羊", "猴", "雞", "狗", "豬" };


		private  static String[] solarTerm = new String[] { "小寒", "大寒", "立春", "雨水", "驚蟄", "春分", "清明", "穀雨", "立夏",
																   "小滿", "芒種", "夏至", "小暑", "大暑", "立秋", "處暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至" };

		private static int[] sTermInfo ={0,21208,42467,63836,85337,107014,128867,150921,173149,195551,218072,240693,263343,285989,308563,331033,353350,375494,397447,419210,440795,462224,483532,504758};

		private  static String[] sFtv = new String[] { "0101 新年元旦",
														 "0202 世界溼地日",
														 "0207 國際聲援南非日",
														 "0210 國際氣象節",
														 "0214 情人節",
														 "0301 國際海豹日",
														 "0303 全國愛耳日",
														 "0308 國際婦女節",
														 "0312 植樹節 孫中山逝世紀念日",
														 "0314 國際警察日",
														 "0315 國際消費者權益日",
														 "0317 中國國醫節 國際航海日",
														 "0321 世界森林日 消除種族歧視國際日",
														 "0321 世界兒歌日",
														 "0322 世界水日",
														 "0323 世界氣象日",
														 "0324 世界防治結核病日",
														 "0325 全國中小學生安全教育日",
														 "0330 巴勒斯坦國土日",
														 "0401 愚人節 全國愛國衛生運動月(四月) 稅收宣傳月(四月)",
														 "0407 世界衛生日",
														 "0422 世界地球日",
														 "0423 世界圖書和版權日",
														 "0424 亞非新聞工作者日",
														 "0501 國際勞動節",
														 "0504 中國五四青年節",
														 "0505 碘缺乏病防治日",
														 "0508 世界紅十字日",
														 "0512 國際護士節",
														 "0515 國際家庭日",
														 "0517 世界電信日",
														 "0518 國際博物館日",
														 "0520 全國學生營養日",
														 "0523 國際牛奶日",
														 "0531 世界無煙日",
														 "0601 國際兒童節",
														 "0605 世界環境日",
														 "0606 全國愛眼日",
														 "0617 防治荒漠化和乾旱日",
														 "0623 國際奧林匹克日",
														 "0625 全國土地日",
														 "0626 國際反毒品日",
														 "0701 中國共產黨建黨日 世界建築日",
														 "0702 國際體育記者日",
														 "0707 中國人民抗日戰爭紀念日",
														 "0711 世界人口日",
														 "0730 非洲婦女日",
														 "0801 中國建軍節",
														 "0808 中國男子節(爸爸節)",
														 "0815 日本正式宣佈無條件投降日",
														 "0908 國際掃盲日 國際新聞工作者日",
														 "0910 教師節",
														 "0914 世界清潔地球日",
														 "0916 國際臭氧層保護日",
														 "0918 九·一八事變紀念日",
														 "0920 全國愛牙日",
														 "0927 世界旅遊日",
														 "1001 國慶節 世界音樂日 國際老人節",
														 "1001 國際音樂日",
														 "1002 國際和平與民主自由鬥爭日",
														 "1004 世界動物日",
														 "1008 全國高血壓日",
														 "1008 世界視覺日",
														 "1009 世界郵政日 萬國郵聯日",
														 "1010 辛亥革命紀念日 世界精神衛生日",
														 "1013 世界保健日 國際教師節",
														 "1014 世界標準日",
														 "1015 國際盲人節(白手杖節)",
														 "1016 世界糧食日",
														 "1017 世界消除貧困日",
														 "1022 世界傳統醫藥日",
														 "1024 聯合國日 世界發展信息日",
														 "1031 世界勤儉日",
														 "1107 十月社會主義革命紀念日",
														 "1108 中國記者日",
														 "1109 全國消防安全宣傳教育日",
														 "1110 世界青年節",
														 "1111 國際科學與和平周(本日所屬的一週)",
														 "1112 孫中山誕辰紀念日",
														 "1114 世界糖尿病日",
														 "1117 國際大學生節 世界學生節",
														 "1121 世界問候日 世界電視日",
														 "1129 國際聲援巴勒斯坦人民國際日",
														 "1201 世界艾滋病日",
														 "1203 世界殘疾人日",
														 "1205 國際經濟和社會發展志願人員日",
														 "1208 國際兒童電視日",
														 "1209 世界足球日",
														 "1210 世界人權日",
														 "1212 西安事變紀念日",
														 "1213 南京大屠殺(1937年)紀念日!緊記血淚史!",
														 "1221 國際籃球日",
														 "1224 平安夜",
														 "1225 聖誕節",
														 "1226 毛主席誕辰",
														 "1229 國際生物多樣性日" };

		private  static String[] lFtv = new String[] { "0101農曆春節","0202 龍擡頭節", "0115 元宵節", "0505 端午節", "0707 七夕情人節", "0815 中秋節",
															  "0909 重陽節", "1208 臘八節", "1224 小年", "0100除夕" };
		
		/// <summary>
		/// 傳回農曆 y年的總天數
		/// </summary>
		/// <param name="y"></param>
		/// <returns></returns>
		 private static int lYearDays(int y) 
			  {
				  int i, sum = 348;
				  for (i = 0x8000; i > 0x8; i >>= 1) 
				  {
					  if ((lunarInfo[y - 1900] & i) != 0)
						  sum += 1;
				  }
				  return (sum + leapDays(y));
			  }

		

		/// <summary>
		/// 傳回農曆 y年閏月的天數
		/// </summary>
		/// <param name="y"></param>
		/// <returns></returns>
		private static int leapDays(int y) 
			  {
				  if (leapMonth(y) != 0) 
				  {
					  if ((lunarInfo[y - 1900] & 0x10000) != 0)
						  return 30;
					  else
						  return 29;
				  } 
				  else
					  return 0;
			  }

		
		/// <summary>
		/// 傳回農曆 y年閏哪個月 1-12 , 沒閏傳回 0
		/// </summary>
		/// <param name="y"></param>
		/// <returns></returns>
		private static int leapMonth(int y) 
			  {
				  return (int) (lunarInfo[y - 1900] & 0xf);
			  }
		
		/// <summary>
		/// 傳回農曆 y年m月的總天數
		/// </summary>
		/// <param name="y"></param>
		/// <param name="m"></param>
		/// <returns></returns>
		private static int monthDays(int y, int m) 
			  {
				  if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0)
					  return 29;
				  else
					  return 30;
			  }


		/// <summary>
		/// 傳回農曆 y年的生肖
		/// </summary>
		/// <param name="y"></param>
		/// <returns></returns>
		private static String AnimalsYear(int y) 
			  {
				  return Animals[(y - 4) % 12];
			  }


		/// <summary>
		/// 傳入 月日的offset 傳回干支,0=甲子
		/// </summary>
		/// <param name="num"></param>
		/// <returns></returns>
		private static String cyclicalm(int num) 
			  {
				  return (Gan[num % 10] + Zhi[num % 12]);
			  }


		/// <summary>
		/// 傳入 offset 傳回干支, 0=甲子
		/// </summary>
		/// <param name="y"></param>
		/// <returns></returns>
		private static String cyclical(int y) 
			  {
				  int num = y - 1900 + 36;
				  return (cyclicalm(num));
			  }


		/// <summary>
		/// 傳出農曆.year0 .month1 .day2 .yearCyl3 .monCyl4 .dayCyl5 .isLeap6
		/// </summary>
		/// <param name="y"></param>
		/// <param name="m"></param>
		/// <returns></returns>
		private long[] Lunar(int y, int m) 
			  {
				  long[] nongDate = new long[7];
				  int i = 0, temp = 0, leap = 0;
				  DateTime baseDate=new DateTime(1900+1900,2,31);
				  DateTime objDate=new DateTime(y+1900,m+1,1);
				  TimeSpan ts=objDate-baseDate;
				  long offset=(long)ts.TotalDays;
				  if (y < 2000)
					  offset += year19[m - 1];
				  if (y > 2000)
					  offset += year20[m - 1];
				  if (y == 2000)
					  offset += year2000[m - 1];
				  nongDate[5] = offset + 40;
				  nongDate[4] = 14;

				  for (i = 1900; i < 2050 && offset > 0; i++) 
				  {
					  temp = lYearDays(i);
					  offset -= temp;
					  nongDate[4] += 12;
				  }
				  if (offset < 0) 
				  {
					  offset += temp;
					  i--;
					  nongDate[4] -= 12;
				  }
				  nongDate[0] = i;
				  nongDate[3] = i - 1864;
				  leap = leapMonth(i); // 閏哪個月
				  nongDate[6] = 0;

				  for (i = 1; i < 13 && offset > 0; i++) 
				  {
					  // 閏月
					  if (leap > 0 && i == (leap + 1) && nongDate[6] == 0) 
					  {
						  --i;
						  nongDate[6] = 1;
						  temp = leapDays((int) nongDate[0]);
					  } 
					  else 
					  {
						  temp = monthDays((int) nongDate[0], i);
					  }

					  // 解除閏月
					  if (nongDate[6] == 1 && i == (leap + 1))
						  nongDate[6] = 0;
					  offset -= temp;
					  if (nongDate[6] == 0)
						  nongDate[4]++;
				  }

				  if (offset == 0 && leap > 0 && i == leap + 1) 
				  {
					  if (nongDate[6] == 1) 
					  {
						  nongDate[6] = 0;
					  } 
					  else 
					  {
						  nongDate[6] = 1;
						  --i;
						  --nongDate[4];
					  }
				  }
				  if (offset < 0) 
				  {
					  offset += temp;
					  --i;
					  --nongDate[4];
				  }
				  nongDate[1] = i;
				  nongDate[2] = offset + 1;
				  return nongDate;
			  }

		 
		/// <summary>
		/// 傳出y年m月d日對應的農曆.year0 .month1 .day2 .yearCyl3 .monCyl4 .dayCyl5 .isLeap6
		/// </summary>
		/// <param name="y"></param>
		/// <param name="m"></param>
		/// <param name="d"></param>
		/// <returns></returns>
		private static long[] calElement(int y, int m, int d) 
			  {
				  long[] nongDate = new long[7];
				  int i = 0, temp = 0, leap = 0;				 
				
				DateTime baseDate=new DateTime(1900,1,31);
			 
				DateTime objDate=new DateTime(y,m,d);
				TimeSpan ts=objDate-baseDate;
			 
				long offset=(long)ts.TotalDays;
				
				  nongDate[5] = offset + 40;
				  nongDate[4] = 14;

				  for (i = 1900; i < 2050 && offset > 0; i++) 
				  {
					  temp = lYearDays(i);
					  offset -= temp;
					  nongDate[4] += 12;
				  }
				  if (offset < 0) 
				  {
					  offset += temp;
					  i--;
					  nongDate[4] -= 12;
				  }
				  nongDate[0] = i;
				  nongDate[3] = i - 1864;
				  leap = leapMonth(i); // 閏哪個月
				  nongDate[6] = 0;

				  for (i = 1; i < 13 && offset > 0; i++) 
				  {
					  // 閏月
					  if (leap > 0 && i == (leap + 1) && nongDate[6] == 0) 
					  {
						  --i;
						  nongDate[6] = 1;
						  temp = leapDays((int) nongDate[0]);
					  } 
					  else 
					  {
						  temp = monthDays((int) nongDate[0], i);
					  }

					  // 解除閏月
					  if (nongDate[6] == 1 && i == (leap + 1))
						  nongDate[6] = 0;
					  offset -= temp;
					  if (nongDate[6] == 0)
						  nongDate[4]++;
				  }

				  if (offset == 0 && leap > 0 && i == leap + 1) 
				  {
					  if (nongDate[6] == 1) 
					  {
						  nongDate[6] = 0;
					  } 
					  else 
					  {
						  nongDate[6] = 1;
						  --i;
						  --nongDate[4];
					  }
				  }
				  if (offset < 0) 
				  {
					  offset += temp;
					  --i;
					  --nongDate[4];
				  }
				  nongDate[1] = i;
				  nongDate[2] = offset + 1;
				  return nongDate;
			  }

		
		private  static String getChinaDate(int day) 
					 {
						 String a = "";
						 if (day == 10)
							 return "初十";
						 if (day == 20)
							 return "二十";
						 if (day == 30)
							 return "三十";
						 int two = (int) ((day) / 10);
						 if (two == 0)
							 a = "初";
						 if (two == 1)
							 a = "十";
						 if (two == 2)
							 a = "廿";
						 if (two == 3)
							 a = "三";
						 int one = (int) (day % 10);
						 switch (one) 
						 {
							 case 1:
								 a += "一";
								 break;
							 case 2:
								 a += "二";
								 break;
							 case 3:
								 a += "三";
								 break;
							 case 4:
								 a += "四";
								 break;
							 case 5:
								 a += "五";
								 break;
							 case 6:
								 a += "六";
								 break;
							 case 7:
								 a += "七";
								 break;
							 case 8:
								 a += "八";
								 break;
							 case 9:
								 a += "九";
								 break;
						 }
						 return a;
					 }


		private static DateTime  sTerm(int y,int n) 
		{
			double ms=31556925974.7*(y-1900);
			double ms1=sTermInfo[n];
			DateTime offDate =new DateTime(1900,1,6,2,5,0);
			offDate=offDate.AddMilliseconds(ms);
			offDate=offDate.AddMinutes(ms1);			
			return offDate;
		}
		/// <summary>
		/// 獲取農曆
		/// </summary>
		/// <param name="dt"></param>
		/// <returns></returns>
		public static CNDate getChinaDate(DateTime dt)
		{
			CNDate cd=new CNDate();
			int year =dt.Year;
			int month =dt.Month;
			int date =dt.Day;
			long[] l = calElement(year, month, date);
			cd.cnIntYear=(int)l[0];
			cd.cnIntMonth=(int)l[1];
			cd.cnIntDay=(int)l[2];
			cd.cnStrYear=cyclical(year);
			cd.cnAnm=AnimalsYear(year);
			cd.cnStrMonth=nStr1[(int) l[1]];
			cd.cnStrDay=getChinaDate((int) (l[2]));
			string smd=dt.ToString("MMdd");

            string lmd = FormatDate(cd.cnIntMonth, cd.cnIntDay);
			for(int i=0;i<solarTerm.Length;i++)
			{
				string s1=sTerm(dt.Year,i).ToString("MMdd");
				if(s1.Equals(dt.ToString("MMdd")))
				{
					cd.cnSolarTerm=solarTerm[i];
					break;
				}				
			}
			foreach(string s in sFtv)
			{
				string s1=s.Substring(0,4);
				if(s1.Equals(smd))
				{
					cd.cnFtvs=s.Substring(4,s.Length-4);
					break;
				}
			}
			foreach(string s in lFtv)
			{
				string s1=s.Substring(0,4);
				if(s1.Equals(lmd))
				{
					cd.cnFtvl=s.Substring(4,s.Length-4);
					break;
				}
			}
			dt=dt.AddDays(1);
			year =dt.Year;
			month =dt.Month;
			date =dt.Day;
			l = calElement(year, month, date);
            lmd = FormatDate((int)l[1], (int)l[2]);
			if(lmd.Equals("0101"))
				cd.cnFtvl="除夕";
			return cd;
		}
        static string FormatDate(int m, int d)
        {
            return string.Format("{0:00}{1:00}",m,d);
        }
	}

    
	public  class CNDate
	{
		/// <summary>
		/// 農曆年(整型)
		/// </summary>
		public int cnIntYear=0;
		/// <summary>
		/// 農曆月份(整型)
		/// </summary>
		public int cnIntMonth=0;
		/// <summary>
		/// 農曆天(整型)
		/// </summary>
		public int cnIntDay=0;
		/// <summary>
		/// 農曆年(支幹)
		/// </summary>
		public string cnStrYear="";
		/// <summary>
		/// 農曆月份(字符)
		/// </summary>
		public string cnStrMonth="";
		/// <summary>
		/// 農曆天(字符)
		/// </summary>
		public string cnStrDay="";
		/// <summary>
		/// 農曆屬象
		/// </summary>
		public string cnAnm="";
		/// <summary>
		/// 二十四節氣
		/// </summary>
		public string cnSolarTerm="";
		/// <summary>
		/// 陰曆節日
		/// </summary>
		public string cnFtvl="";
		/// <summary>
		/// 陽曆節日
		/// </summary>
		public string cnFtvs="";
	}


	


}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章