c#農歷日歷類

KirSNVD 8年前發布 | 1K 次閱讀 C# 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()即可獲得農歷相關字段。

 本文由用戶 KirSNVD 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!