废话不多说,直接上代码namespace BLL
{
   public class Nongli
    {
       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 Nongli()
{
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 getNongli(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农历日;
}    }
}
首先很感谢你认真的阅读完这个算法,  你可以拿去试试, 年份传2012年以前, 农历都可以算出,今年是2012年,我传DateTime.Now得到2012传进去,居然给我返回无效的公历年份, 看来世界末日真的来了

解决方案 »

  1.   

    作为高端人才,你丫连bug都跟2012扯上关系了?
      

  2.   

    “m_i最大公历年份 = 2011;
     m_i最小公历年份 = 1900;”   if ((i公历年 < m_i最小公历年份) || (i公历年 > m_i最大公历年份))----最大是你的2011了当然2012是无效的了你把‘m_i最大公历年份’的值重新设置一下就好了
    { //如果不是有效公历日期,退出。
        return "无效公历年份";
    }
      

  3.   

    哈哈哈哈,这个小bug 居然被你们发现了  呵呵呵呵呵呵呵呵
      

  4.   

    System.Globalization.ChineseLunisolarCalendar这个类就是.net自带的农历算法,不需要象lz这么辛苦。
      

  5.   

    参考JavaScript源代码
    1900-2050年超酷百年日历。来自网络,经本人整理优化。 
    http://download.csdn.net/detail/zhao4zhong1/1211949
      

  6.   

        class Program
        {
            static void Main(string[] args)
            {
                System.Globalization.ChineseLunisolarCalendar chineseLunisolarCalendar = new System.Globalization.ChineseLunisolarCalendar();
                DateTime date = DateTime.Now;  
                int year = chineseLunisolarCalendar.GetYear(date);
                int month = chineseLunisolarCalendar.GetMonth(date);
                int day = chineseLunisolarCalendar.GetDayOfMonth(date);
                Console.WriteLine(string.Format("公历:{0} 农历:{1}", date.ToString("yyyy-MM-dd"), (year + "-" + month + "-" + day)));
                Console.Read();
            }
        }
      

  7.   


    闰月与节气有关,我们通常说24节气,其实是12个节气和12个中气,如果赶上某个月只有节气没有中气,那么这个月就要置闰。想靠计算得出也是可能的,不过太过复杂,当初曾经研究过一段时间,从网上下载了1.6个G的天文学相关资料,因为农历每个月的长短实际上是完全根据月球的朔望来定的,而由于星体之间的相互引力作用,各种天体的运行并不是完全可计算的,月亮绕地球运行的周期也不是固定的。目前能计算到2100年就算是很长的了,记得前两年还出现过很多日历都把农历弄错一天的事情,然后我发现我原来用Delphi做的那个农历就错了,那是网上流传很广的一个农历日期对照表。当时我看了一下准确算出来的结果,月朔的时间是零时几十秒,可能原来计算的程序计算的时间是零时之前,所以造成了那个月的农历正好差了一天。目前做农历的绝大部分还都是采用查表法的,比较方便快捷。用纯计算的方式也无法保证100年后是否准确。