基於組件的C#農曆算法


// 下面是一個關於C#的農曆算法
// 日期數據定義方法如下
// 前12個字節代表1-12月爲大月或是小月,1爲大月30天,0爲小月29天,
// 第13位爲閏月的情況,1爲大月30天,0爲小月29天,第14、15位爲閏月的月
// 份,使用10進製表示。最後4位爲當年家農曆新年-即農曆1月1日所在公曆
// 的日期,如0131代表1月31日。
// 日期函數使用方式如下i公曆年爲要輸入的公曆年,i公曆月爲公曆月,i公曆日爲
// 公曆日,返回值爲:屬相 ,天干地支,農曆年農曆月農曆日。


using System;

namespace 農曆組件
{
 public class 農曆
 {
  private string[] m_str農曆日曆表;
  private string[] m_str天干地支表;
  private string m_str屬相表;
  private string m_str農曆月表;
  private string m_str農曆日表;
  private int m_i最大公曆年份;
  private int m_i最小公曆年份;

  public 農曆()
  {
   m_str農曆日曆表 = new string[] {
     "0100101101101080131",
     "0100101011100000219",
     "1010010101110000208",
     "0101001001101050129",
     "1101001001100000216",
     "1101100101010000204",
     "0110101010101040125",
     "0101011010100000213",
     "1001101011010000202",
     "0100101011101020122",
     "0100101011100000210",
     "1010010011011060130",
     "1010010011010000218",
     "1101001001010000206",
     "1101010101001050126",
     "1011010101010000214",
     "0101011010100000204",
     "1001011011010020123",
     "1001010110110000211",
     "0100100110111070201",
     "0100100110110000220",
     "1010010010110000208",
     "1011001001011050128",
     "0110101001010000216",
     "0110110101000000205",
     "1010110110101040124",
     "0010101101100000213",
     "1001010101110000202",
     "0100100101111020123",
     "0100100101110000210",
     "0110010010110060130",
     "1101010010100000217",
     "1110101001010000206",
     "0110110101001050126",
     "0101101011010000214",
     "0010101101100000204",
     "1001001101110030124",
     "1001001011100000211",
     "1100100101101070131",
     "1100100101010000219",
     "1101010010100000208",
     "1101101001010060127",
     "1011010101010000215",
     "0101011010100000205",
     "1010101011011040125",
     "0010010111010000213",
     "1001001011010000202",
     "1100100101011020122",
     "1010100101010000210",
     "1011010010101070129",
     "0110110010100000217",
     "1011010101010000206",
     "0101010110101050127",
     "0100110110100000214",
     "1010010110110000203",
     "0101001010111030124",
     "0101001010110000212",
     "1010100101010080131",
     "1110100101010000218",
     "0110101010100000208",
     "1010110101010060128",
     "1010101101010000215",
     "0100101101100000205",
     "1010010101110040125",
     "1010010101110000213",
     "0101001001100000202",
     "1110100100110030121",
     "1101100101010000209",
     "0101101010101070130",
     "0101011010100000217",
     "1001011011010000206",
     "0100101011101050127",
     "0100101011010000215",
     "1010010011010000203",
     "1101001001101040123",
     "1101001001010000211",
     "1101010100101080131",
     "1011010101000000218",
     "1011011010100000207",
     "1001011011010060128",
     "1001010110110000216",
     "0100100110110000205",
     "1010010010111040125",
     "1010010010110000213",
     "1011001001011100202",
     "0110101001010000220",
     "0110110101000000209",
     "1010110110101060129",
     "1010101101100000217",
     "1001001101110000206",
     "0100100101111050127",
     "0100100101110000215",
     "0110010010110000204",
     "0110101001010030123",
     "1110101001010000210",
     "0110101100101080131",
     "0101101011000000219",
     "1010101101100000207",
     "1001001101101050128",
     "1001001011100000216",
     "1100100101100000205",
     "1101010010101040124",
     "1101010010100000212",
     "1101101001010000201",
     "0101101010101020122",
     "0101011010100000209",
     "1010101011011070129",
     "0010010111010000218",
     "1001001011010000207",
     "1100100101011050126",
     "1010100101010000214",
     "1011010010100000214"   
   };
   m_str屬相表 = "鼠牛虎兔龍蛇馬羊猴雞狗豬";
   m_str農曆月表 = "正二三四五六七八九十寒臘";
   m_str農曆日表 = "初一初二初三初四初五初六初七初八初九初十十一十二十三十四十五十六十七十八十九二十廿一廿二廿三廿四廿五廿六廿七廿八廿九三十";
   m_i最大公曆年份 = 2011;
   m_i最小公曆年份 = 1900;

   string str天干 = "甲乙丙丁戊已庚辛壬癸";
   string str地支 = "子醜寅卯辰巳午未申酉戌亥";
   m_str天干地支表 = new string[60];
   for (int i = 0; i < 60; i++)
   {
    m_str天干地支表[i] = str天干.Substring(i % 10, 1) + str地支.Substring(i % 12, 1);
   }

  }

  public string 日期(int i公曆年,
                             int i公曆月,
                             int i公曆日)
  {
      if ( (i公曆年 < m_i最小公曆年份)  || (i公曆年 > m_i最大公曆年份) )
      { //如果不是有效公曆日期,退出。
    return "無效公曆年份";
   }

   // 計算農曆年
   int i農曆年;
   int i農曆月;
   int i農曆日;


   i農曆年 = i公曆年;
   // 農曆新年月份
   i農曆月 = Convert.ToInt32((m_str農曆日曆表[i農曆年 - m_i最小公曆年份].Substring(15, 2)));
   // 農曆新年日子
   i農曆日= Convert.ToInt32((m_str農曆日曆表[i農曆年 - m_i最小公曆年份].Substring(17, 2)));;
   
   if ( (i公曆月 < i農曆月) || ( (i公曆月 == i農曆月) && (i公曆日 < i農曆日)) )
   {
    i農曆年--;
    // 農曆新年月份
    i農曆月 = Convert.ToInt32((m_str農曆日曆表[i農曆年 - m_i最小公曆年份].Substring(15, 2)));
    // 農曆新年日子
    i農曆日= Convert.ToInt32((m_str農曆日曆表[i農曆年 - m_i最小公曆年份].Substring(17, 2)));;
   }
   
   // 計算農曆月
   DateTime dt公曆日期 = new DateTime(i公曆年, i公曆月, i公曆日);
   DateTime dt農曆日期 = new DateTime(i農曆年, i農曆月, i農曆日);
   TimeSpan ts日期差 = dt公曆日期 - dt農曆日期;
   int i天數 = ts日期差.Days;

   i農曆月 = 1;
   i農曆日 = 1;
   bool b閏月 = false;
   for (int i = 0; i < i天數; i++)
   {
    i農曆日++;
    if (i農曆日 == 30 + Convert.ToInt32(m_str農曆日曆表[i農曆年 - m_i最小公曆年份].Substring(i農曆月 - 1, 1)) ||
    (b閏月 && ( i農曆日 == 30 + Convert.ToInt32( m_str農曆日曆表[i農曆年 - m_i最小公曆年份].Substring(12, 1) ) )) )
    {
     if ( (b閏月 == false) && (i農曆月 == Convert.ToInt32(m_str農曆日曆表[i農曆年 - m_i最小公曆年份].Substring(13, 2))) )
     {
      b閏月= true;
     }
     else
     {
      b閏月 = false;
      i農曆月++;
     }
     i農曆日 = 1;
    }
    else
    {
    }
   }
   
   // 計算農曆日
   string str農曆日 = m_str農曆日表.Substring((i農曆日 -1) * 2, 2);
   
   // 計算農曆月
   string str農曆月 = m_str農曆月表.Substring(i農曆月 - 1, 1) + "月";
   if (b閏月)
   {
    str農曆月 = "閏" + str農曆月;
   }
   
   // 農曆年
   string str農曆年 = Convert.ToString(i農曆年, 10) + "年";
   
   // 計算天干地支
   string str天干地支 = m_str天干地支表[ (i農曆年 - 4) % 60 ];

   // 計算屬相
   string str屬相 = m_str屬相表.Substring((i農曆年 - 4) % 12, 1);
   
   // 返回農曆日期
   return str屬相 + "," + str天干地支 + "," + str農曆年 + str農曆月 + str農曆日;
  }
 }
}

參考:VB計算農曆的算法    thinkeasy

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章