農歷日歷C#實現類

xdfr 9年前發布 | 2K 次閱讀 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++;
        }
    }
    

    } }</pre>

    初始化類之后,使用方法ComputeChineseFields()即可獲得農歷相關字段。


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