阳历(公历)转农历

来源:互联网 发布:逆向 java web 编辑:程序博客网 时间:2024/04/27 17:35


网上找了一些阳历转农历的代码,但总是有些对不上。

参照百度万年历和好记星的日历,实现了一下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-20190x07954, 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 , 没闰传回 0int 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 .monCylstruct 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;}