http://210.77.145.209/csdn/resource/index.asp?class=5
不过是用Delphi写的,自己改改Pascal语言源代码。

解决方案 »

  1.   


    大富翁的朋友可参考如下贴子:
    http://www.delphibbs.com/delphibbs/dispq.asp?LID=388272随没有解决,但毕竟有不少提示!
    其中一贴:来自:黄耀彰 时间:00-12-6 0:02:21 ID:410607  
        你这个问题可不太好答,但是绝对是个好问题。为此我特请教学地理的朋友,归纳如下:
        1、我国的农历是一种阴阳历1912年以前用。
        2、我国的农历强调逐年逐月推算。通过逐月推算后才知道某年某月是大月还
    是小月;通过逐年推算后,才知道某年是闰年还是平年。
        3、我国传统历法一直是阴阳历和二十四气并行,二十四气适用于农业生产。 
        4、我国传统历法采用干支循环(六十甲子)为周期的纪时制度。历日的推算有两条原则:
        1、以月相定日序。即以日月合朔的日期和时刻来定每月的初一。
           例如,如果今天6时5 分是日月合朔的时刻,则今天是初一。如果第二个
           日月合朔落在第30天,那么该月是小月(29天);如果落在第31天,那么
           该月是大月(30天);
        2、以中气定月序。
           我国的旧历把全年分二十四个节气,其中单数的叫节气,双数的叫中气。
           以雨水所在的月为正月;以春分所在的月为定为二月;以此类推。
           规定,平年有十二个月,闰年有十三个月,在没有中气的历月叫闰月,
           把闰月看成是前一月的重复,月序同上一月。关于节气与阳历(公历)的关系:
        节气是按太阳黄经来划分的,在地球绕太阳转的每15度为一个节气,所以
        节气与公历的日期是相对较固定的,每个公历平年的节气位置是固定的;
        而公历的闰年的节气比平年的节气的位置要前一日。如2000年(闰)其冬至
        12月21日,而2001年(平)的冬至是22日的。实现:
        1、公历中二十四节气很简单,
        2、农历要找到一个基准日(日月合朔的日期),才可按逐年逐月推算出日序
    与月序;闰年与闰月。   
        3、再根据干支循环(六十甲子)定年就容易了。    公式可不好写,但算法肯定是有的!以上是我的一些想法,希望对你有帮助,
    做好后别忘了Copy一份给我。 
     
      

  2.   

    发信人: smhwang@phoenix (全自动之狼), 信区: programming
    标  题: --- 西历与农历转换函式 ---
    发信站: 交大资工凤凰城资讯站 (wed jul 26 01:51:17 1995)
    转信站: phoenix
    origin: kscg-ts5.kscg.gov.tw本函式欢迎各站各版转载, 无须经本人同意. 若对历法有兴趣, 欢迎讨论./*
     
      西历农历转换程式    黄晓鸣  1995,7,25
     
      prototype:  int calconv( struct convdate * );
     
      struct convdate
      {
        int source;       ==0 则输入日期为西历, !=0 则输入为农历
        int solaryear;    输出或输入之西历年份
        int solarmonth;   西历月
        int solardate;    西历日
        int lunaryear;    输出或输入之农历年份
        int lunarmonth;   农历月
        int lunardate;    农历日
        int weekday;      该日为星期几 ( 0==星期日, 1==星期一, ... )
        int kan;          该日天干     ( 0==甲, 1==乙, ..., 9==癸 )
        int chih;         该日地支     ( 0==子, 1==丑, ..., 11==亥 )
      };
     
      呼叫时须设定 souce 的值, 若为 0 则为西历转农历, 否则为农历转西历. 然後视
      输入为西历或农历来设定西历或农历的年月日. 转换後的年月日会填入结构中( 农
      历或西历 ), 以及该日为星期几, 天干地支.
      若函式的返回值为 0 表示没有错误, 1 为输入之年份错误, 2 为输入之月份错误,
      3 为输入之日期错误.
      输入之西历年须在 1937 - 2031 间
      输入之农历年须在 1936 - 2030 间
      若须扩充, 则增加 lunarcal[]
     
    */
     
    #define firstyear 1936  /* the first year in lunarcal[] */struct convdate
     {
      int source;
      int solaryear;
      int solarmonth;
      int solardate;
      int lunaryear;
      int lunarmonth;
      int lunardate;
      int weekday;
      int kan;
      int chih;
     };
     
     struct taglunarcal
     {
      int basedays;         /* 到西历 1 月 1 日到农历正月初一的累积日数 */
      int intercalation;    /* 闰月月份. 0==此年没有闰月 */
      int baseweekday;      /* 此年西历 1 月 1 日为星期几再减 1 */
      int basekanchih;      /* 此年西历 1 月 1 日之干支序号减 1 */
      int monthdays[13];    /* 此农历年每月之大小, 0==小月(29日), 1==大月(30日) */
     };
     
     struct taglunarcal lunarcal[] = {
      { 23,  3, 2, 17, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0 },  /* 1936 */
      { 41,  0, 4, 23, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1 },
      { 30,  7, 5, 28, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 },
      { 49,  0, 6, 33, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
      { 38,  0, 0, 38, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },  /* 1940 */
      { 26,  6, 2, 44, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
      { 45,  0, 3, 49, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },
      { 35,  0, 4, 54, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
      { 24,  4, 5, 59, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 },  /* 1944 */
      { 43,  0, 0,  5, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1 },
      { 32,  0, 1, 10, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 },
      { 21,  2, 2, 15, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
      { 40,  0, 3, 20, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },  /* 1948 */
      { 28,  7, 5, 26, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
      { 47,  0, 6, 31, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1 },
      { 36,  0, 0, 36, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },
      { 26,  5, 1, 41, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 },  /* 1952 */
      { 44,  0, 3, 47, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1 },
      { 33,  0, 4, 52, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 },
      { 23,  3, 5, 57, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 },
      { 42,  0, 6,  2, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 },  /* 1956 */
      { 30,  8, 1,  8, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
      { 48,  0, 2, 13, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
      { 38,  0, 3, 18, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 },
      { 27,  6, 4, 23, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 },  /* 1960 */
      { 45,  0, 6, 29, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0 },
      { 35,  0, 0, 34, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
      { 24,  4, 1, 39, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 },
      { 43,  0, 2, 44, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 },  /* 1964 */
      { 32,  0, 4, 50, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 },
      { 20,  3, 5, 55, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 },
      { 39,  0, 6,  0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
      { 29,  7, 0,  5, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1 },  /* 1968 */
      { 47,  0, 2, 11, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
      { 36,  0, 3, 16, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0 },
      { 26,  5, 4, 21, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1 },
      { 45,  0, 5, 26, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 },  /* 1972 */
      { 33,  0, 0, 32, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1 },
      { 22,  4, 1, 37, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 },
      { 41,  0, 2, 42, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1 },
      { 30,  8, 3, 47, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 },  /* 1976 */
      { 48,  0, 5, 53, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1 },
      { 37,  0, 6, 58, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
      { 27,  6, 0,  3, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0 },
      { 46,  0, 1,  8, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0 },  /* 1980 */
      { 35,  0, 3, 14, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1 },
      { 24,  4, 4, 19, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 },
      { 43,  0, 5, 24, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 },
      { 32, 10, 6, 29, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1 },  /* 1984 */
      { 50,  0, 1, 35, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
      { 39,  0, 2, 40, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1 },
      { 28,  6, 3, 45, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0 },
      { 47,  0, 4, 50, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 },  /* 1988 */
      { 36,  0, 6, 56, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0 },
      { 26,  5, 0,  1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1 },
      { 45,  0, 1,  6, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0 },
      { 34,  0, 2, 11, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0 },  /* 1992 */
      { 22,  3, 4, 17, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
      { 40,  0, 5, 22, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
      { 30,  8, 6, 27, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1 },
      { 49,  0, 0, 32, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1 },  /* 1996 */
      { 37,  0, 2, 38, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
      { 27,  5, 3, 43, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1 },
      { 46,  0, 4, 48, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1 },
      { 35,  0, 5, 53, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 },  /* 2000 */
      { 23,  4, 0, 59, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
      { 42,  0, 1,  4, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
      { 31,  0, 2,  9, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
      { 21,  2, 3, 14, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1 },  /* 2004 */
      { 39,  0, 5, 20, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
      { 28,  7, 6, 25, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 },
      { 48,  0, 0, 30, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1 },
      { 37,  0, 1, 35, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 },  /* 2008 */
      { 25,  5, 3, 41, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
      { 44,  0, 4, 46, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
      { 33,  0, 5, 51, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
      { 22,  4, 6, 56, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },  /* 2012 */
      { 40,  0, 1,  2, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },
      { 30,  9, 2,  7, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 },
      { 49,  0, 3, 12, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1 },
      { 38,  0, 4, 17, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 },  /* 2016 */
      { 27,  6, 6, 23, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 },
      { 46,  0, 0, 28, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0 },
      { 35,  0, 1, 33, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 },
      { 24,  4, 2, 38, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },  /* 2020 */
      { 42,  0, 4, 44, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 },
      { 31,  0, 5, 49, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 },
      { 21,  2, 6, 54, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 },
      { 40,  0, 0, 59, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 },  /* 2024 */
      { 28,  6, 2,  5, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 },
      { 47,  0, 3, 10, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1 },
      { 36,  0, 4, 15, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 },
      { 25,  5, 5, 20, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 },  /* 2028 */
      { 43,  0, 0, 26, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 },
      { 32,  0, 1, 31, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0 },
      { 22,  3, 2, 36, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0 } };
      
    #define lastyear (firstyear+sizeof(lunarcal)/sizeof(struct taglunarcal)-1)
      
      /* 西历年每月之日数 */
      int solarcal[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
      
      /* 西历年每月之累积日数, 平年与闰年 */
      int solardays[2][14] = {
       { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 396 },
       { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366, 397 } };
       
       /* 求此西历年是否为闰年, 返回 0 为平年, 1 为闰年 */
       int getleap( int year )
       {
        if ( year % 400 == 0 )
         return 1;
        else if ( year % 100 == 0 )
         return 0;
        else if ( year % 4 == 0 )
         return 1;
        else
         return 0;
       }
       
       /* 西历农历转换 */
       int calconv( struct convdate *cd )
       {
        int leap, d, sm, y, im, l1, l2, acc, i, lm, kc;
        if ( cd->source == 0 )  /* solar */
        {
         if ( cd->solaryear <= firstyear || cd->solaryear > lastyear )
          return 1;
         sm = cd->solarmonth - 1;
         if ( sm < 0 || sm > 11 )
          return 2;
         leap = getleap( cd->solaryear );
         if ( sm == 1 )
          d = leap + 28;
         else
          d = solarcal[sm];
         if ( cd->solardate < 1 || cd->solardate > d )
          return 3;
         y = cd->solaryear - firstyear;
         acc = solardays[leap][sm] + cd->solardate;
         cd->weekday = ( acc + lunarcal[y].baseweekday ) % 7;
         kc = acc + lunarcal[y].basekanchih;
         cd->kan = kc % 10;
         cd->chih = kc % 12;
         if ( acc <= lunarcal[y].basedays )
         {
          y--;
          cd->lunaryear = cd->solaryear - 1;
          leap = getleap( cd->lunaryear );
          sm += 12;
          acc = solardays[leap][sm] + cd->solardate;
         }
         else
          cd->lunaryear = cd->solaryear;
         l1 = lunarcal[y].basedays;
         for ( i=0; i<13; i++ )
         {
          l2 = l1 + lunarcal[y].monthdays[i] + 29;
          if ( acc <= l2 )
           break;
          l1 = l2;
         }
         cd->lunarmonth = i + 1;
         cd->lunardate = acc - l1;
         im = lunarcal[y].intercalation;
         if ( im != 0 && cd->lunarmonth > im )
         {
          cd->lunarmonth--;
          if ( cd->lunarmonth == im )
           cd->lunarmonth = -im;
         }
         if ( cd->lunarmonth > 12 )
          cd->lunarmonth -= 12;
        }
        else  /* lunar */
        {
         if ( cd->lunaryear < firstyear || cd->lunaryear >= lastyear )
          return 1;
         y = cd->lunaryear - firstyear;
         im = lunarcal[y].intercalation;
         lm = cd->lunarmonth;
         if ( lm < 0 )
         {
          if ( lm != -im )
           return 2;
         }
         else if ( lm < 1 || lm > 12 )
          return 2;
         if ( im != 0 )
         {
          if ( lm > im )
           lm++;
          else if ( lm == -im )
           lm = im + 1;
         }
         lm--;
         if ( cd->lunardate > lunarcal[y].monthdays[lm] + 29 )
          return 3;
         acc = lunarcal[y].basedays;
         for ( i=0; i<lm; i++ )
          acc += lunarcal[y].monthdays[i] + 29;
         acc += cd->lunardate;
         leap = getleap( cd->lunaryear );
         for ( i=13; i>=0; i-- )
          if ( acc > solardays[leap][i] )
           break;
          cd->solardate = acc - solardays[leap][i];
          if ( i <= 11 )
          {
           cd->solaryear = cd->lunaryear;
           cd->solarmonth = i + 1;
          }
          else
          {
           cd->solaryear = cd->lunaryear + 1;
           cd->solarmonth = i - 11;
          }
          leap = getleap( cd->solaryear );
          y = cd->solaryear - firstyear;
          acc = solardays[leap][cd->solarmonth-1] + cd->solardate;
          cd->weekday = ( acc + lunarcal[y].baseweekday ) % 7;
          kc = acc + lunarcal[y].basekanchih;
          cd->kan = kc % 10;
          cd->chih = kc % 12;
        }
        return 0;
    }