C# 农历与阳历相关工具转换类

本文介绍了C#中实现阳历与农历相互转换的工具类,包括阳历转农历和农历转阳历的方法,适用于需要进行日期转换的C#开发场景。

很久之前的东西,又要用了弄出来整理一下

忘性比较大

阳历转农历

//该命名空间下

using System.Globalization;

//有专门计算中国农历的类

ChineseLunisolarCalendar cnsc = new ChineseLunisolarCalendar();

        ChineseLunisolarCalendar cnsc = new ChineseLunisolarCalendar();
        DateTime jrLDate = new DateTime(2024, 1, 1);
        int year = cnsc.GetYear(jrLDate);
        // 是否有闰月,返回正整数(比如2023年闰2月,返回值为3)
        int flag = cnsc.GetLeapMonth(year);
        //有闰月则实际月份减1
        int month = flag > 0 ? cnsc.GetMonth(jrLDate) - 1 : cnsc.GetMonth(jrLDate);
        int day = cnsc.GetDayOfMonth(jrLDate);
        MessageBox.Show("农历:"+year+"年"+month+"月"+day+"日");

 农历转阳历

//接上序 这是把上面被转换成农历的日期 又转换回去了 所以输出的还是2024-01-01
month = flag > 0 ? month + 1 : month; //有闰月则月份加1后转换
DateTime ylDate = cnsc.ToDateTime(year, month, day, 0, 0, 0, 0);
MessageBox.Show("阳历:"+ylDate);

//可以直接调用输出农历对应阳历
DateTime ylDate = cnsc.ToDateTime(jrLDate.Year, jrLDate.Month, jrLDate.Day, 0, 0, 0, 0);

扩展 

//调用类中的方法
DateTime jrLDate = DateTime.Now();
DateTime dtnl=ChinaDate.GetDateFromLunarDate(jrLDate);//农历转阳历
DateTime dtnl=ChinaDate.GetSunYearDate(jrLDate);//阳历转农历
//其他方法自行查看

    /// <summary>

    /// 农历与阴历之间相互转化工具类

    /// </summary>

    public class ChinaDate
    {

        #region 农历信息获取

        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("0501", "劳动节");

            gHoliday.Add("0504", "青年节");

            gHoliday.Add("0601", "儿童节");

            gHoliday.Add("0701", "建党节");

            gHoliday.Add("0801", "建军节");

            gHoliday.Add("0910", "教师节");

            gHoliday.Add("1001", "国庆节");

            gHoliday.Add("1224", "平安夜");

            gHoliday.Add("1225", "圣诞节");


            //农历节日

            nHoliday.Add("0101", "春节");

            nHoliday.Add("0115", "元宵节");

            nHoliday.Add("0505", "端午节");

            nHoliday.Add("0815", "中秋节");

            nHoliday.Add("0909", "重阳节");

            nHoliday.Add("1208", "腊八节");

        }


        /// <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);

            if (strHoliday != "")
            {

                str += " " + strHoliday;

            }

            string strChinaHoliday = GetChinaHoliday(dt);

            if (strChinaHoliday != "")
            {

                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 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 += 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;

        }


        /// <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)
        {

            string strReturn = "";

            object g = gHoliday[dt.Month.ToString("00") + dt.Day.ToString("00")];

            if (g != null)
            {

                strReturn = g.ToString();

            }


            return strReturn;

        }


        /// <summary>

        /// 获取农历节日

        /// </summary>

        /// <param name="dt"></param>

        /// <returns></returns>

        public static string GetChinaHoliday(DateTime dt)
        {

            string strReturn = "";

            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)
                {

                    if (strReturn == "")
                    {

                        strReturn = n.ToString();

                    }

                    else
                    {

                        strReturn += " " + n.ToString();

                    }

                }

            }


            return strReturn;

        }

        #endregion


        #region 阴历-阳历-转换

        /// <summary>
        /// 获取指定年份春节当日(正月初一)的阳历日期
        /// </summary>
        /// <param name="year">指定的年份</param>
        private static DateTime GetLunarNewYearDate(int year)
        {
            DateTime dt = new DateTime(year, 1, 1);
            int cnYear = china.GetYear(dt);
            int cnMonth = china.GetMonth(dt);

            int num1 = 0;
            int num2 = china.IsLeapYear(cnYear) ? 13 : 12;

            while (num2 >= cnMonth)
            {
                num1 += china.GetDaysInMonth(cnYear, num2--);
            }

            num1 = num1 - china.GetDayOfMonth(dt) + 1;
            return dt.AddDays(num1);
        }

        /// <summary>
        /// 阴历转阳历
        /// </summary>
        /// <param name="year">阴历年</param>
        /// <param name="month">阴历月</param>
        /// <param name="day">阴历日</param>
        /// <param name="IsLeapMonth">是否闰月</param>
        public static DateTime GetDateFromLunarDate(int year, int month, int day, bool IsLeapMonth)
        {
            if (year < 1902 || year > 2100)
                throw new Exception("只支持1902~2100期间的农历年");
            if (month < 1 || month > 12)
                throw new Exception("表示月份的数字必须在1~12之间");

            if (day < 1 || day > china.GetDaysInMonth(year, month))
                throw new Exception("农历日期输入有误");

            int num1 = 0, num2 = 0;
            int leapMonth = china.GetLeapMonth(year);

            if (((leapMonth == month + 1) && IsLeapMonth) || (leapMonth > 0 && leapMonth <= month))
                num2 = month;
            else
                num2 = month - 1;

            while (num2 > 0)
            {
                num1 += china.GetDaysInMonth(year, num2--);
            }

            DateTime dt = GetLunarNewYearDate(year);
            return dt.AddDays(num1 + day - 1);
        }

        /// <summary>
        /// 阴历转阳历
        /// </summary>
        /// <param name="date">阴历日期</param>
        /// <param name="IsLeapMonth">是否闰月</param>
        public static DateTime GetDateFromLunarDate(DateTime date, bool IsLeapMonth)
        {
            int year = china.GetYear(date);
            int iMonth = china.GetMonth(date);
            int leapMonth = china.GetLeapMonth(year);
            bool isLeapMonth = iMonth == leapMonth;
            return GetDateFromLunarDate(date.Year, date.Month, date.Day, isLeapMonth);
        }

        /// <summary>

        /// 阳历转为阴历

        /// </summary>

        /// <param name="dt">公历日期</param>

        /// <returns>农历的日期</returns>

        public static DateTime GetSunYearDate(DateTime dt)
        {

            int year = china.GetYear(dt);

            int iMonth = china.GetMonth(dt);

            int iDay = china.GetDayOfMonth(dt);

            int leapMonth = china.GetLeapMonth(year);

            bool isLeapMonth = iMonth == leapMonth;

            if (leapMonth != 0 && iMonth >= leapMonth)
            {

                iMonth--;

            }

            string str = string.Format("{0}-{1}-{2}", year, iMonth, iDay);

            DateTime dtNew = DateTime.Now;

            try
            {

                dtNew = Convert.ToDateTime(str); //防止出现2月份时,会出现超过时间,出现“2015-02-30”这种错误日期

            }

            catch
            {

            }

            return dtNew;

        }

        #endregion


    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值