农历日历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()即可获得农历相关字段。