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