您的位置:首页 > 其它

阳历(公历)转农历

2011-08-23 15:47 260 查看
网上找了一些阳历转农历的代码,但总是有些对不上。

参照百度万年历和好记星的日历,实现了一下1900-2099年之间的阳历转农历。

#include <iostream>

using namespace std;

struct LunarDate
{
int year;
int month;
int day;
bool isLeap;
int yearCyl;//cyclic天干地支
int monCyl;
int dayCyl;
};

int lunarInfo[]=
{
// 1899年:0x0AB50
0x04BD8, 0x04AE0, 0x0A570, 0x054D5, 0x0D260, 0x0D950, 0x16554, 0x056A0, 0x09AD0, 0x055D2,   // 1900-1909
0x04AE0, 0x0A5B6, 0x0A4D0, 0x0D250, 0x1D255, 0x0B540, 0x0D6A0/*0x1D295,0x0B550,0x056A0*/, 0x0ADA2, 0x095B0, 0x14977,   // 1910-1919
0x04970, 0x0A4B0, 0x0B4B5, 0x06A50, 0x06D40, 0x1AB54, 0x02B60, 0x09570, 0x052F2, 0x04970,   // 1920-1929
0x06566, 0x0D4A0, 0x0EA50, 0x06E95/*0x16A95*/, 0x05AD0, 0x02B60, 0x186E3, 0x092E0, 0x1C8D7, 0x0C950,   // 1930-1939
0x0D4A0, 0x1D8A6, 0x0B550, 0x056A0, 0x1A5B4, 0x025D0, 0x092D0, 0x0D2B2, 0x0A950, 0x0B557,   // 1940-1949
0x06CA0, 0x0B550, 0x15355, 0x04DA0, 0x0A5B0, 0x14573, 0x052B0, 0x0A9A8, 0x0E950, 0x06AA0,   // 1950-1959
0x0AEA6, 0x0AB50, 0x04B60, 0x0AAE4, 0x0A570, 0x05260, 0x0F263, 0x0D950, 0x05B57, 0x056A0,   // 1960-1969
0x096D0, 0x04DD5, 0x04AD0, 0x0A4D0, 0x0D4D4, 0x0D250, 0x0D558, 0x0B540, 0x0B6A0, 0x195A6,   // 1970-1979
0x095B0, 0x049B0, 0x0A974, 0x0A4B0, 0x0B27A, 0x06A50, 0x06D40, 0x0AF46, 0x0AB60, 0x09570,   // 1980-1989
0x04AF5, 0x04970, 0x064B0, 0x074A3, 0x0EA50, 0x06B58, 0x055C0/*0x05AC0*/, 0x0AB60, 0x096D5, 0x092E0,   // 1990-1999
0x0C960, 0x0D954, 0x0D4A0, 0x0DA50, 0x07552, 0x056A0, 0x0ABB7, 0x025D0, 0x092D0, 0x0CAB5,   // 2000-2009
0x0A950, 0x0B4A0, 0x0BAA4, 0x0AD50, 0x055D9, 0x04BA0, 0x0A5B0, 0x15176, 0x052B0, 0x0A930,   // 2010-2019
0x07954, 0x06AA0, 0x0AD50, 0x05B52, 0x04B60, 0x0A6E6, 0x0A4E0, 0x0D260, 0x0EA65, 0x0D530,   // 2020-2029
0x05AA0, 0x076A3, 0x096D0, 0x04BD7/*0x04AFB*/, 0x04AD0, 0x0A4D0, 0x1D0B6, 0x0D250, 0x0D520, 0x0DD45,   // 2030-2039
0x0B5A0, 0x056D0, 0x055B2, 0x049B0, 0x0A577, 0x0A4B0, 0x0AA50, 0x1B255, 0x06D20, 0x0ADA0,   // 2040-2049
// 增加2050-2100年数据
0x14B63, 0x09370, 0x049F8, 0x04970, 0x064B0, 0x168A6, 0x0EA50, 0x06B20, 0x1A6C4, 0x0AAE0,   // 2050-2059
0x092E0, 0x0D2E3, 0x0C960, 0x0D557, 0x0D4A0, 0x0DA50, 0x05D55, 0x056A0, 0x0A6D0, 0x055D4,   // 2060-2069
0x052D0, 0x0A9B8, 0x0A950, 0x0B4A0, 0x0B6A6, 0x0AD50, 0x055A0, 0x0ABA4, 0x0A5B0, 0x052B0,   // 2070-2079
0x0B273, 0x06930, 0x07337, 0x06AA0, 0x0AD50, 0x14B55, 0x04B60, 0x0A570, 0x054E4, 0x0D260,   // 2080-2089
0x0E968, 0x0D520, 0x0DAA0, 0x16AA6, 0x056D0, 0x04AE0, 0x0A9D4, 0x0A4D0, 0x0D150, 0x0F252,   // 2090-2099
0x0D520,                                                                                    // 2100
};

//==== 传回农历 y年闰哪个月 1-12 , 没闰传回 0
int GetLunarLeapMonth(int y)
{
return(lunarInfo[y-1900] & 0xf);
}

//==== 传回农历 y年闰月的天数
int GetLunarLeapDays(int y)
{
if(GetLunarLeapMonth(y))  return((lunarInfo[y-1900] & 0x10000)? 30: 29);
else return(0);
}

//==== 传回农历 y年的总天数
int GetLunarYearDays(int y)
{
int i, sum = 348;
for(i=0x8000; i>0x8; i>>=1) sum += (lunarInfo[y-1900] & i)? 1: 0;
return sum+GetLunarLeapDays(y);
}

//====================================== 传回农历 y年m月的总天数
int GetLunarMonthDays(int y,int m)
{
if ( y >= 1900 )
return(lunarInfo[y-1900] & (0x10000>>m))? 30: 29 ;
else if ( (y == 1899) && (m == 12) )
return 30;
else
return 0;
}

int GetSolarYearDays(int year)
{
if(year%4==0&&year%100!=0||year%400==0)
return 366;
else
return 365;
}
int GetSolarMonthDays(int year,int month)
{
if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)
return 31;
if(month==4||month==6||month==9||month==11)
return 30;
if(month==2&&GetSolarYearDays(year)==366)
return 29;
else
return 28;
}

int GetDaysFrom19000131(int solarYear, int solarMonth,int solarDay)
{
int     nRecYear;
int     nDays;
// 1900年不是闰年,2000年是闰年,所以从1901年起每4年必有一个闰年
if ( solarYear >= 1901 )
{
nRecYear = solarYear - 1901;
nDays = (nRecYear * 365) + (nRecYear / 4);
nDays += 365;   // 1900年是365天
}
else
{
nDays = 0;
}

for (int i = 1; i < solarMonth; i++)
nDays += GetSolarMonthDays(solarYear,i);

nDays += (solarDay - 31);

return  nDays;
}
//==== 算出农历, 传入日期物件, 传回农历日期物件
//     该物件属性有 .year .month .day .isLeap .yearCyl .dayCyl .monCyl
struct LunarDate GetLunar(int solaryear, int solarmonth,int day)
{
struct LunarDate lunar;
int i, leap=0, temp=0;
int offset   = GetDaysFrom19000131(solaryear,solarmonth,day);
lunar.dayCyl = offset + 40;
lunar.monCyl = 14;

for(i=1900; i< 2100 && offset>0; i++)
{
temp=GetLunarYearDays(i);
if (offset < temp)
break;
offset-=temp;
}

lunar.year = i;
lunar.yearCyl = i-1864;
leap = GetLunarLeapMonth(i); //闰哪个月
lunar.isLeap = false;

for(i=1; i<13; i++)
{
//闰月
if(leap>0 && i==(leap+1) && !lunar.isLeap)
{
--i;
lunar.isLeap = true;
temp = GetLunarLeapDays(lunar.year);
}
else
{
temp = GetLunarMonthDays(lunar.year, i);
}
//解除闰月
if(lunar.isLeap && i==(leap+1))
{
lunar.isLeap = false;
}
if (offset < temp)
break;
offset -= temp;
}

lunar.month = i;
lunar.day = offset + 1;
return lunar;
}

int main(int argc,char** args)
{
struct LunarDate lunar = GetLunar(2011,8,23);
cout<<lunar.year<<"-"<<lunar.month<<"-"<<lunar.day<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: