| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4564 人关注过本帖
标题:用c如何编写 农历转换成公历
只看楼主 加入收藏
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:2 
有没有算法描述?
2011-03-03 18:48
lucky563591
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:765
专家分:2103
注 册:2009-11-18
收藏
得分:2 
有公式吗?
2011-03-04 07:56
小草鸟
Rank: 1
等 级:新手上路
帖 子:7
专家分:0
注 册:2011-1-26
收藏
得分:0 
经过学习,我发现农历这东西是没有算法的。要靠查表来实现。但是很奇怪的是:公历的1990-1-1 转成农历为1989-12-5(没有问题)
                                                                         但是农历的1989-12-5转成公历却是:1989-13-1(有问题) 请问上面的农历转公历的代码中哪里错了。求解释!
2011-03-04 09:23
小草鸟
Rank: 1
等 级:新手上路
帖 子:7
专家分:0
注 册:2011-1-26
收藏
得分:0 
#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");
}

找到别外一个,不过有些错误的,请高手过来看看,并修改修改好吗????

本程序中,公历转农历是网上找的,没有问题~~~
农历转公历时,如果本年不是闰年的话,也没有问题~~~~
但是,当那一年是闰年时,农历转公历算出来就不对!
但是我也不知道到底该咋改~~~
请大家帮我看看~~~多谢了~~~
2011-03-04 11:11
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
实在是没精力研究这方面的知识……
2011-03-04 20:29
木叶_随风
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2012-9-17
收藏
得分:0 
int monthTotal[13] = {0,31,59,90,120,151,181,212,243,273,304,334,365};
int monthTotalLeap[13] = {0,31,60,91,121,152,182,213,244,274,305,335,366};
hjz toSolar(hjz lunar)
{
    int year = lunar.year,
        month = lunar.month,
        day = lunar.day;
    bool leapmonth = lunar.leapmonth;
    int byNow, xMonth, i, j;
    hjz solar;
    /*******计算正月初一离一月一日(元旦)的天数*********/
    byNow = (lunar200y[year-1901] & 0x001F) - 1;
    if( ((lunar200y[year-1901]&0x0060)>>5) == 2)
        byNow += 31;
    /*******计算闰的月数*******/
    xMonth = (lunar200y[year - 1901] & 0xf00000)>>20;
   
    if(leapmonth)
    {
        for(j=1; j<=month; j++)
        {
            if( ( lunar200y[year - 1901] & (0x80000 >> (i-1)) ) ==0)
            {
                 byNow += 29;
            }
            else
                 byNow += 30;
        }
    }
    else
    {
        for(i = 1; i < month; i ++)
        {
            if(xMonth != 0)
            {
                if(i <= xMonth)
                {
                    if( ( lunar200y[year - 1901] & (0x80000 >> (i-1)) ) ==0)
                    {
                         byNow += 29;
                    }
                    else
                         byNow += 30;
                }
                else
                {
                    if( ( lunar200y[year - 1901] & (0x80000 >> i) ) ==0)
                    {
                         byNow += 29;
                    }
                    else
                         byNow += 30;

                }
            }
            else
            {
                if( ( lunar200y[year - 1901] & (0x80000 >> (i-1)) ) ==0)
                {
                    byNow += 29;
                }
                else
                    byNow += 30;
            }
        }//end of for(i =1; i<month; i++)

        
        if(xMonth != 0)
        {
            if(month > xMonth)
            {
                 if((lunar200y[year-1901] & (0x80000>>xMonth))==0)
                      byNow += 29;
                 else
                      byNow += 30;
            }
        }
    }

    byNow += day;

    if(byNow > 366 ||(year%4!=0 && byNow == 365))
    {
        if(year%4==0)
             byNow -= 366;
        else
             byNow -= 365;
        year += 1;
    }
    if(year % 4 == 0)
    {
        for(i=1;i<=13;i++)
        {
            if(monthTotalLeap[i] >= byNow)
            {
                month = i;
                break;
            }
        }
    }
    else
    {
        for(i=1;i<=13;i++)
        {
            if(monthTotal[i] >= byNow)
            {
                month = i;
                break;
            }
        }
    }

if(month <= 2)
{
    solar.day = byNow - monthTotal[month-1];
}   
else
{
    if(year % 4 == 0)
    {
        solar.day = byNow - monthTotaLeap[month-1];
    }
    else
    {
        solar.day = byNow - monthTotal[month-1];
    }
}
    solar.month = month;
    solar.year = year;
    return solar;
}



注:我只改了你的tosolar()函数,对于上面判断是否是闰月的,这里没有接口函数l_CalcLunarDate()和CalcDateDiff()来实现对leapmonth的赋值,所以可以吧该条件下的代码去掉,这样的话就无法将闰月里的日期转化为公历日期了。


[ 本帖最后由 木叶_随风 于 2012-9-17 17:38 编辑 ]
2012-09-17 17:06
木叶_随风
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2012-9-17
收藏
得分:0 
上面有两个错误:
1、第一个for循环里的if语句里应是j-1;
2、if(byNow > 366 || (year%4!=0 && byNow == 365)) 应改为 if(byNow >366 || (year%4!=0 && byNow > 365))
2012-09-21 16:59
快速回复:用c如何编写 农历转换成公历
数据加载中...
 
   



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

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