C# lunar calendar and solar calendar related tool conversion class

I need to take out things from a long time ago and sort them out after using them again.

relatively forgetful

Gregorian calendar to lunar calendar

//Under this namespace

using System.Globalization;

//There is a class dedicated to calculating the Chinese lunar calendar

ChineseLunisolarCalendar cnsc = new ChineseLunisolarCalendar();

 ChineseLunisolarCalendar cnsc = new ChineseLunisolarCalendar();
        DateTime jrLDate = new DateTime(2024, 1, 1);
        int year = cnsc.GetYear(jrLDate);
        // Whether there is a leap month, return a positive integer (for example, in leap February in 2023, the return value is 3)
        int flag = cnsc.GetLeapMonth(year);
        //If there is a leap month, the actual month is subtracted by 1
        int month = flag > 0 ? cnsc.GetMonth(jrLDate) - 1 : cnsc.GetMonth(jrLDate);
        int day = cnsc.GetDayOfMonth(jrLDate);
        MessageBox.Show("Lunar calendar:" + year + "year" + month + "month" + day + "day");

Converting lunar calendar to solar calendar

//Continued from the previous sequence. This is to convert the date that was converted to the lunar calendar and back again, so the output is still 2024-01-01.
month = flag > 0 ? month + 1 : month; //If there is a leap month, the month will be converted by adding 1
DateTime ylDate = cnsc.ToDateTime(year, month, day, 0, 0, 0, 0);
MessageBox.Show("Gregorian calendar: " + ylDate);

//Can be directly called to output the lunar calendar corresponding to the solar calendar
DateTime ylDate = cnsc.ToDateTime(jrLDate.Year, jrLDate.Month, jrLDate.Day, 0, 0, 0, 0);

Extensions

//Call methods in the class
DateTime jrLDate = DateTime.Now();
DateTime dtnl=ChinaDate.GetDateFromLunarDate(jrLDate);//Convert lunar calendar to solar calendar
DateTime dtnl=ChinaDate.GetSunYearDate(jrLDate);//Convert solar calendar to lunar calendar
//Other methods to view by yourself

    /// <summary>

    /// Tool class for converting between lunar calendar and lunar calendar

    /// </summary>

    public class ChinaDate
    {

        #region Lunar calendar information acquisition

        private static ChineseLunisolarCalendar china = new ChineseLunisolarCalendar();

        private static Hashtable gHoliday = new Hashtable();

        private static Hashtable nHoliday = new Hashtable();

        private static string[] JQ = { "Little Cold", "Dahan", "Beginning of Spring", "Rain", "Jingzhe", "Spring Equinox", "Qingming", "Grain Rain", "Beginning of Summer", "Xiaoman", "Earn Grain" ", "summer solstice", "little heat", "big heat", "beginning of autumn", "end of summer", "white dew", "autumnal equinox", "cold dew", "frost fall", "beginning of winter", "light snow", "heavy snow", "winter solstice" };

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


        static ChinaDate()
        {

            //Gregorian calendar holidays

            gHoliday.Add("0101", "New Year's Day");

            gHoliday.Add("0214", "Valentine's Day");

            gHoliday.Add("0305", "Lei Feng Day");

            gHoliday.Add("0308", "Women's Day");

            gHoliday.Add("0312", "Arbor Day");

            gHoliday.Add("0315", "Consumer Rights Day");

            gHoliday.Add("0401", "April Fool's Day");

            gHoliday.Add("0501", "Labor Day");

            gHoliday.Add("0504", "Youth Day");

            gHoliday.Add("0601", "Children's Day");

            gHoliday.Add("0701", "Party Day");

            gHoliday.Add("0801", "Army Day");

            gHoliday.Add("0910", "Teacher's Day");

            gHoliday.Add("1001", "National Day");

            gHoliday.Add("1224", "Christmas Eve");

            gHoliday.Add("1225", "Christmas");


            //Lunar Festival

            nHoliday.Add("0101", "Spring Festival");

            nHoliday.Add("0115", "Lantern Festival");

            nHoliday.Add("0505", "Dragon Boat Festival");

            nHoliday.Add("0815", "Mid-Autumn Festival");

            nHoliday.Add("0909", "Double Ninth Festival");

            nHoliday.Add("1208", "Laba Festival");

        }


        /// <summary>

        /// Get the lunar calendar

        /// </summary>

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

        /// <returns></returns>

        public static string GetChinaDate(DateTime dt)
        {

            if (dt > china.MaxSupportedDateTime || dt < china.MinSupportedDateTime)
            {

                //Date range: February 19, 1901 - January 28, 2101

                throw new Exception(string.Format("Date out of range! Must be between {0} and {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>

        /// Get the lunar year

        /// </summary>

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

        /// <returns></returns>

        public static string GetYear(DateTime dt)
        {

            int yearIndex = china.GetSexagenaryYear(dt);

            string yearTG = "A, B, C, D, Wu, Ji, Geng, Xin, Rengui";

            string yearDZ = "Zi Chou Yin Mao Chen Si Wu Wei Shen You Xu Hai";

            string yearSX = "Rat, Ox, Tiger, Rabbit, Dragon, Snake, Horse, Sheep, Monkey, Chicken, Dog, Pig";

            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>

        /// Get the lunar month

        /// </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 & amp; & amp; iMonth >= leapMonth)
            {

                iMonth--;

            }


            string szText = "Positive two, three, four, five, six, seven, eight, ninety";

            string strMonth = isLeapMonth ? "Leap" : "";

            if (iMonth <= 10)
            {

                strMonth + = szText.Substring(iMonth - 1, 1);

            }

            else if (iMonth == 11)
            {

                strMonth + = "Eleven";

            }

            else
            {

                strMonth + = "Rax";

            }

            return strMonth + "month";

        }


        /// <summary>

        /// Get the lunar date

        /// </summary>

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

        /// <returns></returns>

        public static string GetDay(DateTime dt)
        {

            int iDay = china.GetDayOfMonth(dt);

            string szText1 = "The twenty-third day of the lunar month";

            string szText2 = "One, two, three, four, five, six, seven, eight, ninety";

            string strDay;

            if (iDay == 20)
            {

                strDay = "twenty";

            }

            else if (iDay == 30)
            {

                strDay = "Thirty";

            }

            else
            {

                strDay = szText1.Substring((iDay - 1) / 10, 1);

                strDay = strDay + szText2.Substring((iDay - 1) % 10, 1);

            }

            return strDay;

        }


        /// <summary>

        /// Get solar terms

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

        /// Get Gregorian calendar holidays

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

        /// Get the lunar festival

        /// </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 = "New Year's Eve";

            }

            else if (leapMonth != iMonth)
            {

                if (leapMonth != 0 & amp; & amp; 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 Lunar Calendar-Solar Calendar-Conversion

        /// <summary>
        /// Get the Gregorian date of the Spring Festival (the first day of the first lunar month) in the specified year
        /// </summary>
        /// <param name="year">Specified 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>
        /// Convert lunar calendar to solar calendar
        /// </summary>
        /// <param name="year">Lunar year</param>
        /// <param name="month">lunar month</param>
        /// <param name="day">lunar day</param>
        /// <param name="IsLeapMonth">Whether it is a leap month</param>
        public static DateTime GetDateFromLunarDate(int year, int month, int day, bool IsLeapMonth)
        {
            if (year < 1902 || year > 2100)
                throw new Exception("Only supports lunar years between 1902 and 2100");
            if (month < 1 || month > 12)
                throw new Exception("The number representing the month must be between 1 and 12");

            if (day < 1 || day > china.GetDaysInMonth(year, month))
                throw new Exception("Incorrect lunar date input");

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

            if (((leapMonth == month + 1) & amp; & amp; IsLeapMonth) || (leapMonth > 0 & amp; & amp; 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>
        /// Convert lunar calendar to solar calendar
        /// </summary>
        /// <param name="date">Lunar calendar date</param>
        /// <param name="IsLeapMonth">Whether it is a leap month</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>

        /// Convert solar calendar to lunar calendar

        /// </summary>

        /// <param name="dt">Gregorian calendar date</param>

        /// <returns>Lunar calendar date</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 & amp; & amp; iMonth >= leapMonth)
            {

                iMonth--;

            }

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

            DateTime dtNew = DateTime.Now;

            try
            {

                dtNew = Convert.ToDateTime(str); //Prevent that when February appears, the time will exceed and the error date such as "2015-02-30" will appear.

            }

            catch
            {

            }

            return dtNew;

        }

        #endregion


    }