农历日历C#实现类

2018-07-20    来源:open-open

容器云强势上线!快速搭建集群,上万Linux镜像随意使用
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()即可获得农历相关字段。


标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点!
本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。

上一篇:spring mvc 日期处理

下一篇:实现中文转拼音的C#类