农历日历C#实现类

using System;
using System.Collections.Generic;
using System.Text;
 
namespace ConsoleApp
{
    /**
  * ChineseCalendarGB.java
  * Copyright (c) 1997-2002 by Dr. Herong Yang
  * 中国农历算法- 实用于公历1901 年至2100 年之间的200 年
  */
    public class CnCalendar
    {
        static fileds
 
        static methods
 
        private int gregorianYear = 1901;
        private int gregorianMonth = 1;
        private int gregorianDate = 1;
        private bool isGregorianLeap;
        private int dayOfYear;
 
        /// <summary>
        /// 周日------- 一星期的第一天
        /// </summary>
        private int dayOfWeek;
        private int chineseYear;
 
        /// <summary>
        /// 负数表示闰月
        /// </summary>
        private int chineseMonth;
 
        private int chineseDate;
 
        //24节气
        private int sectionalTerm;
        private int principleTerm;
 
        public CnCalendar()
        {
            SetGregorian(1901, 1, 1);
        }
 
        public void SetGregorian(int y, int m, int d)
        {
            gregorianYear = y;
            gregorianMonth = m;
            gregorianDate = d;
            isGregorianLeap = IsGregorianLeapYear(y);
            dayOfYear = DayOfYear(y, m, d);
            dayOfWeek = DayOfWeek(y, m, d);
            chineseYear = 0;
            chineseMonth = 0;
            chineseDate = 0;
            sectionalTerm = 0;
            principleTerm = 0;
        }
 
        /// <summary>
        /// 根据设定的公历(阳历)年月人计算农历年月日天干地支
        /// </summary>
        /// <returns>是否得到结果,得到结果为0,否则为1</returns>
        public int ComputeChineseFields()
        {
            if (gregorianYear < 1901 || gregorianYear > 2100) return 1;
            int startYear = baseYear;
            int startMonth = baseMonth;
            int startDate = baseDate;
            chineseYear = baseChineseYear;
            chineseMonth = baseChineseMonth;
            chineseDate = baseChineseDate;
            // 第二个对应日,用以提高计算效率
            // 公历2000 年1 月1 日,对应农历4697 年11 月25 日
            if (gregorianYear >= 2000)
            {
                startYear = baseYear + 99;
                startMonth = 1;
                startDate = 1;
                chineseYear = baseChineseYear + 99;
                chineseMonth = 11;
                chineseDate = 25;
            }
            int daysDiff = 0;
            for (int i = startYear; i < gregorianYear; i++)
            {
                daysDiff += 365;
                if (IsGregorianLeapYear(i)) daysDiff += 1; // leap year
            }
            for (int i = startMonth; i < gregorianMonth; i++)
            {
                daysDiff += DaysInGregorianMonth(gregorianYear, i);
            }
            daysDiff += gregorianDate - startDate;
 
            chineseDate += daysDiff;
            int lastDate = DaysInChineseMonth(chineseYear, chineseMonth);
            int nextMonth = NextChineseMonth(chineseYear, chineseMonth);
            while (chineseDate > lastDate)
            {
                if (Math.Abs(nextMonth) < Math.Abs(chineseMonth)) chineseYear++;
                chineseMonth = nextMonth;
                chineseDate -= lastDate;
                lastDate = DaysInChineseMonth(chineseYear, chineseMonth);
                nextMonth = NextChineseMonth(chineseYear, chineseMonth);
            }
            return 0;
        }
 
        /// <summary>
        /// 计算24节气
        /// </summary>
        /// <returns></returns>
        public int ComputeSolarTerms()
        {
            if (gregorianYear < 1901 || gregorianYear > 2100) return 1;
            sectionalTerm = SectionalTerm(gregorianYear, gregorianMonth);
            principleTerm = PrincipleTerm(gregorianYear, gregorianMonth);
            return 0;
        }
 
        public override string ToString()
        {
            StringBuilder buf = new StringBuilder();
            buf.Append("Gregorian Year: " + gregorianYear + "\n");
            buf.Append("Gregorian Month: " + gregorianMonth + "\n");
            buf.Append("Gregorian Date: " + gregorianDate + "\n");
            buf.Append("Is Leap Year: " + isGregorianLeap + "\n");
            buf.Append("Day of Year: " + dayOfYear + "\n");
            buf.Append("Day of Week: " + dayOfWeek + "\n");
            buf.Append("Chinese Year: " + chineseYear + "\n");
            buf.Append("Heavenly Stem: " + TIANGAN_NAMES[((chineseYear - 1) % 10)] + "\n");
            buf.Append("Earthly Branch: " + DIZHI_NAMES[((chineseYear - 1) % 12)] + "\n");
            buf.Append("Chinese Month: " + chineseMonth + "\n");
            buf.Append("Chinese Date: " + chineseDate + "\n");
            buf.Append("Sectional Term: " + sectionalTerm + "\n");
            buf.Append("Principle Term: " + principleTerm + "\n");
            return buf.ToString();
        }
 
        /// <summary>
        /// 计算指定日期的明天的农历
        /// </summary>
        public void RollUpOneDay()
        {
            dayOfWeek = dayOfWeek % 7 + 1;
            dayOfYear++;
            gregorianDate++;
            int days = DaysInGregorianMonth(gregorianYear, gregorianMonth);
            if (gregorianDate > days)
            {
                gregorianDate = 1;
                gregorianMonth++;
                if (gregorianMonth > 12)
                {
                    gregorianMonth = 1;
                    gregorianYear++;
                    dayOfYear = 1;
                    isGregorianLeap = IsGregorianLeapYear(gregorianYear);
                }
                sectionalTerm = SectionalTerm(gregorianYear, gregorianMonth);
                principleTerm = PrincipleTerm(gregorianYear, gregorianMonth);
            }
            chineseDate++;
            days = DaysInChineseMonth(chineseYear, chineseMonth);
            if (chineseDate > days)
            {
                chineseDate = 1;
                chineseMonth = NextChineseMonth(chineseYear, chineseMonth);
                if (chineseMonth == 1) chineseYear++;
            }
        }
    }
}

初始化类之后,使用方法ComputeChineseFields()即可获得农历相关字段。

posted @ 2022-03-25 16:36  电子_精灵  阅读(116)  评论(0编辑  收藏  举报