标题:关于公历农历互相转换的一个小程序的问题~~!
只看楼主
ilylia
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2008-3-2
 问题点数:0 回复次数:2 
关于公历农历互相转换的一个小程序的问题~~!
本程序中,公历转农历是网上找的,没有问题~~~
农历转公历时,如果本年不是闰年的话,也没有问题~~~~
但是,当那一年是闰年时,农历转公历算出来就不对!
但是我也不知道到底该咋改~~~
请大家帮我看看~~~多谢了~~~

程序代码:
#include "stdio.h"

static const unsigned short wMonthAdd[13]={0,31,59,90,120,151,181,212,243,273,304,334,365};
static const unsigned short wMonthAddy[13]={0,31,60,91,121,152,182,213,244,274,305,335,366};

static const unsigned long wNongliData[99]={/*农历数据*/
0x41A95,0x00D4A,0x00DA5,0x20B55,0x0056A,0x7155B,0x0025D,0x0092D,0x5192B,0x00A95,
0x00B4A,0x416AA,0x00AD5,0x90AB5,0x004BA,0x00A5B,0x60A57,0x0052B,0x00A93,0x40E95,
0x006AA,0x00AD5,0x209B5,0x004B6,0x612AE,0x00A4E,0x00D26,0x51D26,0x00D53,0x005AA,
0x30D6A,0x0096D,0xB095D,0x004AD,0x00A4D,0x61A4B,0x00D25,0x00D52,0x51B54,0x00B5A,
0x0056D,0x2095B,0x0049B,0x71497,0x00A4B,0x00AA5,0x516A5,0x006D2,0x00ADA,0x30AB6,
0x00937,0x8092F,0x00497,0x0064B,0x60D4A,0x00EA5,0x006B2,0x4156C,0x00AAE,0x0092E,
0x3192E,0x00C96,0x71A95,0x00D4A,0x00DA5,0x50B55,0x0056A,0x00A6D,0x40A5D,0x0052D,
0x8152B,0x00A95,0x00B4A,0x616AA,0x00AD5,0x0055A,0x414BA,0x00A5B,0x0052B,0x31527,
0x00693,0x70E53,0x006AA,0x00AD5,0x509B5,0x004B6,0x00A57,0x40A4E,0x00D26,0x81D26,
0x00D52,0x00DAA,0x60D6A,0x0056D,0x004AE,0x4149D,0x00A4D,0x00D15,0x21B25};

typedef struct
{
    int     day;
    int     month;
    int     year;
} CLK_DATE_T;

CLK_DATE_T GetOldDay(CLK_DATE_T pSt)                   /*公历转换成农历*/
{
static int wCurYear,wCurMonth,wCurDay;
static int nIsEnd,m,k,n,i,nBit;
static long nTheDate;
CLK_DATE_T OldDay;
int y;
wCurYear  = pSt.year;
wCurMonth = pSt.month;
wCurDay   = pSt.day;
y=wCurYear - 2001;

/*计算该天到2001年正月初一有多少天*/
nTheDate =(y<<8)+(y<<6)+(y<<5)+(y<<3)+(y<<2)+y + (y>>2) + wCurDay + wMonthAdd[wCurMonth - 1] - 23;
if((!(wCurYear & 0x0003)) && (wCurMonth > 2))
  nTheDate++;
nIsEnd = 0;
m      = 0;
while(nIsEnd != 1){
              if(wNongliData[m] < 4095)  k = 11; 
            else k = 12;

             n = k;
              while(n>=0){
                       nBit = wNongliData[m];
                       for(i=1;i<n+1;i++) nBit = (nBit>>1);
                       nBit = (nBit & 0x0001);
                       if (nTheDate <= (29 + nBit))
                    {
                         nIsEnd = 1;
                         break;
                       }
                       nTheDate = nTheDate - 29 - nBit;
                      n--;
                      }
              if(nIsEnd) break;
              m++;
            }
wCurYear  = 2001 + m;
wCurMonth = k - n + 1;
wCurDay   = nTheDate;

y=wNongliData[m] / 65536 + 1;                   /*计算该年闰月的月份+1*/

if (k == 12){

  if (wCurMonth == y)
      wCurMonth = 1 - wCurMonth;
  else if (wCurMonth > y)
      wCurMonth = wCurMonth - 1;
}
OldDay.year =wCurYear;
OldDay.month=wCurMonth;
OldDay.day  =wCurDay;
return OldDay;
}

CLK_DATE_T GetNewDay(CLK_DATE_T pSt)                      /*农历转换成公历*/
{
    CLK_DATE_T Begin,NewDay;
    CLK_DATE_T ODay;
    int wCurMonth,wCurDay,nDate,monthdays[13];
    int cc,k,i,yy,j,nBit,monthP,monthN,yyy,allday;
    long nTheDate;
    cc=pSt.year-2001;
    nDate=0;
    nTheDate=0;

  /*************************************************************
   *********        我估计这里也有问题          ****************
   *************************************************************/
    Begin.year=pSt.year;
    for(i=1;i<3;i++)                         /*计算该年正月初一到元旦的天数*/
    {
        for(j=1;j<32;j++)
        {
            Begin.month=i;
            Begin.day=j;
            ODay = GetOldDay(Begin);
            if(ODay.month==1 && ODay.day==1)
                break;
            nDate++;
        }
    }
  /*************************************************************
   *************************************************************/

    if(wNongliData[cc] < 4095)  k = 11;
    else k = 12;
    j=k;
    while(j>=0)                              /*计算该年农历每月多少天*/
    {
        nBit = wNongliData[cc];
        for(i=1;i<j+1;i++) nBit = (nBit>>1);
        nBit = (nBit & 0x0001);
        monthdays[k-j]=29+nBit;
        j--;
    }
    
    wCurMonth = pSt.month;
    wCurDay   = pSt.day;

  /*************************************************************
   *********        我估计问题就在下面          ****************
   *************************************************************/

    yy=wNongliData[cc] / 65536;
    if (k==12 && yy<wCurMonth)        wCurMonth++;
    if (wCurMonth<0)        wCurMonth=-1*wCurMonth+1;
    for(i=0;i<wCurMonth-1;i++)    nTheDate+=monthdays[i];

  /*************************************************************
   *********        我估计问题就在上面          ****************
   *************************************************************/

    nTheDate+=wCurDay+nDate;
    
    NewDay.year=pSt.year;

    yyy=(!(NewDay.year%4) && (NewDay.year%100)) || !(NewDay.year%400);
    if(yyy)        allday=366;
    else        allday=365;
    if(nTheDate>allday)
    {
        nTheDate-=allday;
        NewDay.year++;
    }
    for(i=1;i<13;i++)
    {
        if(yyy)
        {
            monthP = wMonthAddy[i-1];
            monthN = wMonthAddy[i];
        }
        else
        {
            monthP = wMonthAdd[i-1];
            monthN = wMonthAdd[i];
        }
        if(monthP<nTheDate && nTheDate<=monthN)
        {
            NewDay.month = i;
            NewDay.day   = nTheDate-monthP;
        }
    }


    return NewDay;
}


void main()
{
    CLK_DATE_T aaa,bbb;
    int i,j,k;
    printf("1:lunar to solar.\n2:solar to lunar.\n");
    printf("Please Input Your Choose:");
    scanf("%d",&k);
    printf("Input the date:\n");
    scanf("%d %d %d",&aaa.year,&aaa.month,&aaa.day);
    switch(k)
    {
        case 2:    bbb=GetOldDay(aaa);break;
        case 1:    bbb=GetNewDay(aaa);
    }
    printf("%d %d %d\n",bbb.year,bbb.month,bbb.day);
    printf("***********************************************\n");
}


其中农历数据的含义如下:
程序代码:
每个数转成2进制,一共32位
低12/13位表示每个月的大小,高16位表示闰哪个月

比如2006年表中10进制464219,16进制0x7155b,二进制

 0000 0000 0000 0111         0001 0101 0101 1011
|--------闰7月--------------|---1 2345 67*8 9---| (*闰月,这里闰7月)

比如2007年表中10进制605,16进制0x25D,二进制

 0000 0000 0000 0000          0000 0010 0101 1011
|--------无闰月--------------|---- 1234 5678 9---|


[[it] 本帖最后由 ilylia 于 2008-3-3 12:11 编辑 [/it]]

change.rar (2.22 KB)
搜索更多相关主题的帖子: 公历 农历 const static 
2008-03-02 01:02
ilylia
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2008-3-2
得分:0 
为什么无人回应啊。。。请帮我看看好吗??
2008-03-03 12:26
xianshizhe111
Rank: 1
等 级:新手上路
帖 子:1451
专家分:0
注 册:2007-12-8
得分:0 
晚上上线的人多点,你再看看.
2008-03-03 13:00



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-201605-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.623984 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved