Algorithm to find the Gregorian date of the Chinese New Year of a certain Gregorian year

依然范特西╮ 提交于 2019-12-21 05:29:04

问题


I am making a driver to calculate various holidays in a given time span. So, I need to find the Gregorian dates of all the Chinese Holidays (Chinese New Year, QingMing Festival, Dragon Boat Festival, etc). I used the famous 'Easter algorithm' for Good Friday, Easter Monday, Ascension Day, and Whit Monday calculations; however, I don't understand it well enough to adapt it for the Chinese calendar.

I have found similar questions, but they often go from Gregorian to Chinese:

Moon / Lunar Phase Algorithm

Calculating lunar/lunisolar holidays in python

http://www.herongyang.com/year/program.html

http://www.hermetic.ch/cal_stud/ch_year.htm

The last link was exremely helpful but I'm still not sure how to implement that algorithm in a way that can help me. Any advice or code would be greatly appreciated!

Here is my Good Friday Algorithm:

private void GetGoodFridayOccurances(DateTime startDate, DateTime endDate,      List<ObservedHoliday> observedHolidays, StandardHoliday holiday)
    {
        for (DateTime date = startDate; date <= endDate; date = date.AddYears(1))
        {
            #region Finding the Day of Easter Algorithm
            int day, month;
            int firstTwo = date.Year / 100;
            int remainderMod = date.Year % 19;
            int pfmDate = (firstTwo - 15) / 2 + 202 - 11 * remainderMod;
            #region switches
            switch (firstTwo)
            {
                case 21:
                case 24:
                case 25:
                case 27:
                case 28:
                case 29:
                case 30:
                case 31:
                case 32:
                case 34:
                case 35:
                case 38:
                    pfmDate = pfmDate - 1;
                    break;
                case 33:
                case 36:
                case 37:
                case 39:
                case 40:
                    pfmDate = pfmDate - 2;
                    break;
            }
            #endregion
            pfmDate = pfmDate % 30;

            int tA = pfmDate + 21;
            if (pfmDate == 29)
                tA = tA - 1;
            if (pfmDate == 29 && remainderMod > 10)
                tA = tA - 1;
            //Find next sunday
            int tB = (tA - 19) % 7;

            int tC = (40 - firstTwo) % 4;
            if (tC == 3 || tC > 1)
                tC = tC + 1;

            pfmDate = date.Year % 100;
            int tD = (pfmDate + pfmDate / 4) % 7;
            int tE = ((20 - tB - tC - tD) % 7) + 1;
            day = tA + tE;

            if (day > 31)
            {
                day = day - 31;
                month = 4;
            }
            else
            {
                month = 3;
            }
            #endregion

            DateTime observed = new DateTime(date.Year, month, day).AddDays(-2);
            ObservedHoliday obsdate = new ObservedHoliday(holiday);
            if (startDate == endDate && startDate.Day == observed.Day)
            {
                obsdate.DateObserved = observed;
                observedHolidays.Add(obsdate);
            }
            else if (startDate != endDate && observed >= startDate)
            {
                obsdate.DateObserved = observed;
                observedHolidays.Add(obsdate);
            }
        }  

回答1:


For Chinese New Year, I think this would work:

ChineseLunisolarCalendar chinese   = new ChineseLunisolarCalendar();
GregorianCalendar        gregorian = new GregorianCalendar();

DateTime utcNow = DateTime.UtcNow;

// Get Chinese New Year of current UTC date/time
DateTime chineseNewYear = chinese.ToDateTime( utcNow.Year, 1, 1, 0, 0, 0, 0 );

// Convert back to Gregorian (you could just query properties of `chineseNewYear` directly, but I prefer to use `GregorianCalendar` for consistency:

Int32 year  = gregorian.GetYear( chineseNewYear );
Int32 month = gregorian.GetMonth( chineseNewYear );
Int32 day   = gregorian.GetDayOfMonth( chineseNewYear );



回答2:


Because the Chinese Calendar is very complex (and based astronomical considerations) there is no simple way to calculate the Gregorian date of a Chinese New Year which is correct in all cases. (There are some 'rules of thumb' which always fail for some years.) For the underlying theory see here and for Windows software to do this (and other Chinese Calendar calculations) see here



来源:https://stackoverflow.com/questions/30719176/algorithm-to-find-the-gregorian-date-of-the-chinese-new-year-of-a-certain-gregor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!