//==============================================================
//  版权所有：深圳杰文科技
//  文件名：ChineseLunisolarCalendarExt.cs
//  版本：V1.0  
//  创建者：Jay  ( QQ： 85363208 )
//  创建时间：2017-11-28 16:18
//  创建描述：
//  修改者：
//  修改时间：
//  修改说明： 
//==============================================================

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace Infrastructure.Utilities
{
	public class CalendarExt
	{
		void Test()
		{
			string s = GetChineseDateTime(DateTime.Parse("2014-11-25"));
			Console.WriteLine(s);
		}

		/// <summary>
		/// 根据公历获取农历日期
		/// </summary>
		/// <param name="datetime">公历日期</param>
		/// <returns></returns>
		public static string GetChineseDateTime(DateTime datetime)
		{
			ChineseLunisolarCalendar cCalendar = new ChineseLunisolarCalendar();

			int lyear = cCalendar.GetYear(datetime);
			int lmonth = cCalendar.GetMonth(datetime);
			int lday = cCalendar.GetDayOfMonth(datetime);

			//获取闰月， 0则表示没有闰月
			int leapMonth = cCalendar.GetLeapMonth(lyear);

			bool isleap = false;

			if (leapMonth > 0)
			{
				if (leapMonth == lmonth)
				{
					//闰月
					isleap = true;
					lmonth--;
				}
				else if (lmonth > leapMonth)
				{
					lmonth--;
				}
			}

			return string.Concat(GetDaxieYear(lyear), "年 农历 ",
				isleap ? "闰" : "",
				GetLunisolarMonth(lmonth), "月", GetLunisolarDay(lday));
		}

		public static string GetChineseMonthDay(DateTime datetime)
		{
			ChineseLunisolarCalendar cCalendar = new ChineseLunisolarCalendar();

			int lyear = cCalendar.GetYear(datetime);
			int lmonth = cCalendar.GetMonth(datetime);
			int lday = cCalendar.GetDayOfMonth(datetime);

			//获取闰月， 0则表示没有闰月
			int leapMonth = cCalendar.GetLeapMonth(lyear);

			bool isleap = false;

			if (leapMonth > 0)
			{
				if (leapMonth == lmonth)
				{
					//闰月
					isleap = true;
					lmonth--;
				}
				else if (lmonth > leapMonth)
				{
					lmonth--;
				}
			}

			return string.Concat(isleap ? "闰" : "", GetLunisolarMonth(lmonth), "月", GetLunisolarDay(lday));
		}

		private static string GetDaxieYear(int year)
		{
			string s = "";
			for (int i = 0; i < 4; i++)
			{
				int p = int.Parse(year.ToString().Substring(i, 1));
				s += daxie[p];
			}
			return s;
		}

		#region 农历年

		private static string[] daxie = { "○", "一", "二", "三", "四", "五", "六", "七", "八", "九" };

		/// <summary>
		/// 十天干
		/// </summary>
		private static string[] tiangan = { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" };

		/// <summary>
		/// 十二地支
		/// </summary>
		private static string[] dizhi = { "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" };

		/// <summary>
		/// 十二生肖
		/// </summary>
		private static string[] shengxiao = { "鼠", "牛", "虎", "免", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" };

		/// <summary>
		/// 返回农历天干地支年 
		/// </summary>
		/// <param name="year">农历年</param>
		/// <returns></returns>
		public static string GetLunisolarYear(int year)
		{
			if (year > 3)
			{
				int tgIndex = (year - 4) % 10;
				int dzIndex = (year - 4) % 12;

				return string.Concat(tiangan[tgIndex], dizhi[dzIndex], "[", shengxiao[dzIndex], "]");
			}

			throw new ArgumentOutOfRangeException("无效的年份!");
		}

		#endregion

		#region 农历月

		/// <summary>
		/// 农历月
		/// </summary>
		private static string[] months = { "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二" };

		/// <summary>
		/// 返回农历月
		/// </summary>
		/// <param name="month">月份</param>
		/// <returns></returns>
		public static string GetLunisolarMonth(int month)
		{
			if (month < 13 && month > 0)
			{
				return months[month - 1];
			}

			throw new ArgumentOutOfRangeException("无效的月份!");
		}

		#endregion

		#region 农历日

		private static string[] days1 = { "初", "十", "廿", "三" };

		/// <summary>
		/// 日
		/// </summary>
		private static string[] days = { "一", "二", "三", "四", "五", "六", "七", "八", "九", "十" };

		/// <summary>
		/// 返回农历日
		/// </summary>
		/// <param name="day"></param>
		/// <returns></returns>
		public static string GetLunisolarDay(int day)
		{
			if (day > 0 && day < 32)
			{
				if (day != 20 && day != 30)
				{
					return string.Concat(days1[(day - 1) / 10], days[(day - 1) % 10]);
				}
				else
				{
					return string.Concat(days[(day - 1) / 10], days1[1]);
				}
			}

			throw new ArgumentOutOfRangeException("无效的日");
		}

		#endregion

		/*************************************************************************/

		private static string NumToUpper(int num)
		{
			String str = num.ToString();
			string rstr = "";
			int n;
			for (int i = 0; i < str.Length; i++)
			{
				n = Convert.ToInt16(str[i].ToString());//char转数字,转换为字符串，再转数字
				switch (n)
				{
					case 0:
						rstr = rstr + "〇";
						break;
					case 1:
						rstr = rstr + "一";
						break;
					case 2:
						rstr = rstr + "二";
						break;
					case 3:
						rstr = rstr + "三";
						break;
					case 4:
						rstr = rstr + "四";
						break;
					case 5:
						rstr = rstr + "五";
						break;
					case 6:
						rstr = rstr + "六";
						break;
					case 7:
						rstr = rstr + "七";
						break;
					case 8:
						rstr = rstr + "八";
						break;
					default:
						rstr = rstr + "九";
						break;


				}

			}
			return rstr;
		}

		//月转化为大写
		public static string MonthToUpper(int month)
		{
			if (month < 10)
			{
				return NumToUpper(month);
			}
			else
				if (month == 10)
				{
					return "十";
				}

				else
				{
					return "十" + NumToUpper(month - 10);
				}
		}

		//日转化为大写
		public static string DayToUpper(int day)
		{
			if (day < 20)
			{
				return MonthToUpper(day);
			}
			else
			{
				String str = day.ToString();
				if (str[1] == '0')
				{
					return NumToUpper(Convert.ToInt16(str[0].ToString())) + "十";

				}
				else
				{
					return NumToUpper(Convert.ToInt16(str[0].ToString())) + "十" + NumToUpper(Convert.ToInt16(str[1].ToString()));
				}
			}
		}

		//日期转换为大写
		public static string DateToUpper(System.DateTime date)
		{
			int year = date.Year;
			int month = date.Month;
			int day = date.Day;
			return NumToUpper(year) + "年" + MonthToUpper(month) + "月" + DayToUpper(day) + "日";
		}
	}
}
