搜档网
当前位置:搜档网 › 公历和农历转换算法详解

公历和农历转换算法详解

公历和农历转换算法详解
公历和农历转换算法详解

公历和农历转换算法详解

//C51写的公历转农历和星期

#define uchar unsigned char

#define uint unsigned int

#include

/*

公历年对应的农历数据,每年三字节,

格式第一字节BIT7-4 位表示闰月月份,值为0 为无闰月,BIT3-0 对应农历第1-4 月的大小第二字节BIT7-0 对应农历第5-12 月大小,第三字节BIT7 表示农历第13 个月大小

月份对应的位为1 表示本农历月大(30 天),为0 表示小(29 天)

第三字节BIT6-5 表示春节的公历月份,BIT4-0 表示春节的公历日期

*/

code uchar year_code[597] = {

0x04,0xAe,0x53, //1901 0

0x0A,0x57,0x48, //1902 3

0x55,0x26,0xBd, //1903 6

0x0d,0x26,0x50, //1904 9

0x0d,0x95,0x44, //1905 12

0x46,0xAA,0xB9, //1906 15

0x05,0x6A,0x4d, //1907 18

0x09,0xAd,0x42, //1908 21

0x24,0xAe,0xB6, //1909

0x04,0xAe,0x4A, //1910

0x6A,0x4d,0xBe, //1911

0x0A,0x4d,0x52, //1912

0x0d,0x25,0x46, //1913

0x5d,0x52,0xBA, //1914

0x0B,0x54,0x4e, //1915

0x0d,0x6A,0x43, //1916

0x29,0x6d,0x37, //1917

0x09,0x5B,0x4B, //1918

0x74,0x9B,0xC1, //1919

0x04,0x97,0x54, //1920

0x0A,0x4B,0x48, //1921

0x5B,0x25,0xBC, //1922

0x06,0xA5,0x50, //1923

0x06,0xd4,0x45, //1924

0x4A,0xdA,0xB8, //1925

0x02,0xB6,0x4d, //1926

0x09,0x57,0x42, //1927

0x24,0x97,0xB7, //1928

0x66,0x4B,0x3e, //1930 0x0d,0x4A,0x51, //1931 0x0e,0xA5,0x46, //1932 0x56,0xd4,0xBA, //1933 0x05,0xAd,0x4e, //1934 0x02,0xB6,0x44, //1935 0x39,0x37,0x38, //1936 0x09,0x2e,0x4B, //1937 0x7C,0x96,0xBf, //1938 0x0C,0x95,0x53, //1939 0x0d,0x4A,0x48, //1940 0x6d,0xA5,0x3B, //1941 0x0B,0x55,0x4f, //1942 0x05,0x6A,0x45, //1943 0x4A,0xAd,0xB9, //1944 0x02,0x5d,0x4d, //1945 0x09,0x2d,0x42, //1946 0x2C,0x95,0xB6, //1947 0x0A,0x95,0x4A, //1948 0x7B,0x4A,0xBd, //1949 0x06,0xCA,0x51, //1950 0x0B,0x55,0x46, //1951 0x55,0x5A,0xBB, //1952 0x04,0xdA,0x4e, //1953 0x0A,0x5B,0x43, //1954 0x35,0x2B,0xB8, //1955 0x05,0x2B,0x4C, //1956 0x8A,0x95,0x3f, //1957 0x0e,0x95,0x52, //1958 0x06,0xAA,0x48, //1959 0x7A,0xd5,0x3C, //1960 0x0A,0xB5,0x4f, //1961 0x04,0xB6,0x45, //1962 0x4A,0x57,0x39, //1963 0x0A,0x57,0x4d, //1964 0x05,0x26,0x42, //1965 0x3e,0x93,0x35, //1966 0x0d,0x95,0x49, //1967 0x75,0xAA,0xBe, //1968 0x05,0x6A,0x51, //1969 0x09,0x6d,0x46, //1970 0x54,0xAe,0xBB, //1971 0x04,0xAd,0x4f, //1972

0x4d,0x26,0xB7, //1974

0x0d,0x25,0x4B, //1975

0x8d,0x52,0xBf, //1976

0x0B,0x54,0x52, //1977

0x0B,0x6A,0x47, //1978

0x69,0x6d,0x3C, //1979

0x09,0x5B,0x50, //1980

0x04,0x9B,0x45, //1981

0x4A,0x4B,0xB9, //1982

0x0A,0x4B,0x4d, //1983

0xAB,0x25,0xC2, //1984

0x06,0xA5,0x54, //1985

0x06,0xd4,0x49, //1986

0x6A,0xdA,0x3d, //1987

0x0A,0xB6,0x51, //1988

0x09,0x37,0x46, //1989

0x54,0x97,0xBB, //1990

0x04,0x97,0x4f, //1991

0x06,0x4B,0x44, //1992

0x36,0xA5,0x37, //1993

0x0e,0xA5,0x4A, //1994

0x86,0xB2,0xBf, //1995

0x05,0xAC,0x53, //1996

0x0A,0xB6,0x47, //1997

0x59,0x36,0xBC, //1998

0x09,0x2e,0x50, //1999 294 0x0C,0x96,0x45, //2000 297 0x4d,0x4A,0xB8, //2001

0x0d,0x4A,0x4C, //2002

0x0d,0xA5,0x41, //2003

0x25,0xAA,0xB6, //2004

0x05,0x6A,0x49, //2005

0x7A,0xAd,0xBd, //2006

0x02,0x5d,0x52, //2007

0x09,0x2d,0x47, //2008

0x5C,0x95,0xBA, //2009

0x0A,0x95,0x4e, //2010

0x0B,0x4A,0x43, //2011

0x4B,0x55,0x37, //2012

0x0A,0xd5,0x4A, //2013

0x95,0x5A,0xBf, //2014

0x04,0xBA,0x53, //2015

0x0A,0x5B,0x48, //2016

0x05,0x2B,0x50, //2018 0x0A,0x93,0x45, //2019 0x47,0x4A,0xB9, //2020 0x06,0xAA,0x4C, //2021 0x0A,0xd5,0x41, //2022 0x24,0xdA,0xB6, //2023 0x04,0xB6,0x4A, //2024 0x69,0x57,0x3d, //2025 0x0A,0x4e,0x51, //2026 0x0d,0x26,0x46, //2027 0x5e,0x93,0x3A, //2028 0x0d,0x53,0x4d, //2029 0x05,0xAA,0x43, //2030 0x36,0xB5,0x37, //2031 0x09,0x6d,0x4B, //2032 0xB4,0xAe,0xBf, //2033 0x04,0xAd,0x53, //2034 0x0A,0x4d,0x48, //2035 0x6d,0x25,0xBC, //2036 0x0d,0x25,0x4f, //2037 0x0d,0x52,0x44, //2038 0x5d,0xAA,0x38, //2039 0x0B,0x5A,0x4C, //2040 0x05,0x6d,0x41, //2041 0x24,0xAd,0xB6, //2042 0x04,0x9B,0x4A, //2043 0x7A,0x4B,0xBe, //2044 0x0A,0x4B,0x51, //2045 0x0A,0xA5,0x46, //2046 0x5B,0x52,0xBA, //2047 0x06,0xd2,0x4e, //2048 0x0A,0xdA,0x42, //2049 0x35,0x5B,0x37, //2050 0x09,0x37,0x4B, //2051 0x84,0x97,0xC1, //2052 0x04,0x97,0x53, //2053 0x06,0x4B,0x48, //2054 0x66,0xA5,0x3C, //2055 0x0e,0xA5,0x4f, //2056 0x06,0xB2,0x44, //2057 0x4A,0xB6,0x38, //2058 0x0A,0xAe,0x4C, //2059 0x09,0x2e,0x42, //2060

0x0C,0x96,0x49, //2062

0x7d,0x4A,0xBd, //2063

0x0d,0x4A,0x51, //2064

0x0d,0xA5,0x45, //2065

0x55,0xAA,0xBA, //2066

0x05,0x6A,0x4e, //2067

0x0A,0x6d,0x43, //2068

0x45,0x2e,0xB7, //2069

0x05,0x2d,0x4B, //2070

0x8A,0x95,0xBf, //2071

0x0A,0x95,0x53, //2072

0x0B,0x4A,0x47, //2073

0x6B,0x55,0x3B, //2074

0x0A,0xd5,0x4f, //2075

0x05,0x5A,0x45, //2076

0x4A,0x5d,0x38, //2077

0x0A,0x5B,0x4C, //2078

0x05,0x2B,0x42, //2079

0x3A,0x93,0xB6, //2080

0x06,0x93,0x49, //2081

0x77,0x29,0xBd, //2082

0x06,0xAA,0x51, //2083

0x0A,0xd5,0x46, //2084

0x54,0xdA,0xBA, //2085

0x04,0xB6,0x4e, //2086

0x0A,0x57,0x43, //2087

0x45,0x27,0x38, //2088

0x0d,0x26,0x4A, //2089

0x8e,0x93,0x3e, //2090

0x0d,0x52,0x52, //2091

0x0d,0xAA,0x47, //2092

0x66,0xB5,0x3B, //2093

0x05,0x6d,0x4f, //2094

0x04,0xAe,0x45, //2095

0x4A,0x4e,0xB9, //2096

0x0A,0x4d,0x4C, //2097

0x0d,0x15,0x41, //2098

0x2d,0x92,0xB5, //2099

};

///月份数据表

code uchar day_code1[9]={0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3}; code uint day_code2[3]={0x111,0x130,0x14e};

/*

调用函数示例:Conversion(c_sun,year_sun,month_sun,day_sun)

如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);

c_sun,year_sun,month_sun,day_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世纪,c_sun=1为19世纪

调用函数后,原有数据不变,读c_moon,year_moon,month_moon,day_moon得出阴历BCD数据*/

bit c_moon;

data uchar year_moon,month_moon,day_moon,week;

/*子函数,用于读取数据表中农历月的大月或小月,如果该月为大返回1,为小返回0*/

bit get_moon_day(uchar month_p,uint table_addr)

{

uchar temp;

switch (month_p)

{

case 1:{temp=year_code[table_addr]&0x08;

if (temp==0)return(0);else return(1);}

case 2:{temp=year_code[table_addr]&0x04;

if (temp==0)return(0);else return(1);}

case 3:{temp=year_code[table_addr]&0x02;

if (temp==0)return(0);else return(1);}

case 4:{temp=year_code[table_addr]&0x01;

if (temp==0)return(0);else return(1);}

case 5:{temp=year_code[table_addr+1]&0x80;

if (temp==0) return(0);else return(1);}

case 6:{temp=year_code[table_addr+1]&0x40;

if (temp==0)return(0);else return(1);}

case 7:{temp=year_code[table_addr+1]&0x20;

if (temp==0)return(0);else return(1);}

case 8:{temp=year_code[table_addr+1]&0x10;

if (temp==0)return(0);else return(1);}

case 9:{temp=year_code[table_addr+1]&0x08;

if (temp==0)return(0);else return(1);}

case 10:{temp=year_code[table_addr+1]&0x04;

if (temp==0)return(0);else return(1);}

case 11:{temp=year_code[table_addr+1]&0x02;

if (temp==0)return(0);else return(1);}

case 12:{temp=year_code[table_addr+1]&0x01;

if (temp==0)return(0);else return(1);}

case 13:{temp=year_code[table_addr+2]&0x80;

if (temp==0)return(0);else return(1);}

}

}

/*

调用函数示例:Conversion(c_sun,year_sun,month_sun,day_sun)

如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);

c_sun,year_sun,month_sun,day_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世

纪,c_sun=1为19世纪

调用函数后,原有数据不变,读c_moon,year_moon,month_moon,day_moon得出阴历BCD数据*/

void Conversion(bit c,uchar year,uchar month,uchar day)

{ //c=0 为21世纪,c=1 为19世纪输入输出数据均为BCD数据uchar temp1,temp2,temp3,month_p;

uint temp4,table_addr;

bit flag2,flag_y;

temp1=year/16; //BCD->hex 先把数据转换为十六进制

temp2=year%16;

year=temp1*10+temp2;

temp1=month/16;

temp2=month%16;

month=temp1*10+temp2;

temp1=day/16;

temp2=day%16;

day=temp1*10+temp2;

//定位数据表地址

if(c==0)

{

table_addr=(year+0x64-1)*0x3;

}

else

{

table_addr=(year-1)*0x3;

}

//定位数据表地址完成

//取当年春节所在的公历月份

temp1=year_code[table_addr+2]&0x60;

temp1=_cror_(temp1,5);

//取当年春节所在的公历月份完成

//取当年春节所在的公历日

temp2=year_code[table_addr+2]&0x1f;

//取当年春节所在的公历日完成

// 计算当年春年离当年元旦的天数,春节只会在公历1月或2月

if(temp1==0x1)

{

temp3=temp2-1;

}

else

{

temp3=temp2+0x1f-1;

}

// 计算当年春年离当年元旦的天数完成

//计算公历日离当年元旦的天数,为了减少运算,用了两个表

//day_code1[9],day_code2[3]

//如果公历月在九月或前,天数会少于0xff,用表day_code1[9],

//在九月后,天数大于0xff,用表day_code2[3]

//如输入公历日为8月10日,则公历日离元旦天数为day_code1[8-1]+10-1

//如输入公历日为11月10日,则公历日离元旦天数为day_code2[11-10]+10-1

if (month<10)

{

temp4=day_code1[month-1]+day-1;

}

else

{

temp4=day_code2[month-10]+day-1;

}

if ((month>0x2)&&(year%0x4==0))

{ //如果公历月大于2月并且该年的2月为闰月,天数加1

temp4+=1;

}

//计算公历日离当年元旦的天数完成

//判断公历日在春节前还是春节后

if (temp4>=temp3)

{ //公历日在春节后或就是春节当日使用下面代码进行运算

temp4-=temp3;

month=0x1;

month_p=0x1; //month_p为月份指向,公历日在春节前或就是春节当日month_p指向首月flag2=get_moon_day(month_p,table_addr);

//检查该农历月为大小还是小月,大月返回1,小月返回0

flag_y=0;

if(flag2==0)temp1=0x1d; //小月29天

else temp1=0x1e; //大小30天

temp2=year_code[table_addr]&0xf0;

temp2=_cror_(temp2,4); //从数据表中取该年的闰月月份,如为0则该年无闰月

while(temp4>=temp1)

{

temp4-=temp1;

month_p+=1;

if(month==temp2)

{

flag_y=~flag_y;

if(flag_y==0)

month+=1;

}

else month+=1;

flag2=get_moon_day(month_p,table_addr);

if(flag2==0)temp1=0x1d;

else temp1=0x1e;

}

day=temp4+1;

}

else

{ //公历日在春节前使用下面代码进行运算

temp3-=temp4;

if (year==0x0)

{

year=0x63;c=1;

}

else year-=1;

table_addr-=0x3;

month=0xc;

temp2=year_code[table_addr]&0xf0;

temp2=_cror_(temp2,4);

if (temp2==0)

month_p=0xc;

else

month_p=0xd; //

/*month_p为月份指向,如果当年有闰月,一年有十三个月,月指向13,无闰月指向12*/ flag_y=0;

flag2=get_moon_day(month_p,table_addr);

if(flag2==0)temp1=0x1d;

else temp1=0x1e;

while(temp3>temp1)

{

temp3-=temp1;

month_p-=1;

if(flag_y==0)month-=1;

if(month==temp2)flag_y=~flag_y;

flag2=get_moon_day(month_p,table_addr);

if(flag2==0)temp1=0x1d;

else temp1=0x1e;

}

day=temp1-temp3+1;

}

c_moon=c; //HEX->BCD ,运算结束后,把数据转换为BCD数据

temp1=year/10;

temp1=_crol_(temp1,4);

temp2=year%10;

year_moon=temp1|temp2;

temp1=month/10;

temp1=_crol_(temp1,4);

temp2=month%10;

month_moon=temp1|temp2;

temp1=day/10;

temp1=_crol_(temp1,4);

temp2=day%10;

day_moon=temp1|temp2;

}

/*函数功能:输入BCD阳历数据,输出BCD星期数据(只允许1901-2099年)

调用函数示例:Conver_week(c_sun,year_sun,month_sun,day_sun)

如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);

c_sun,year_sun,month_sun,day_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世纪,c_sun=1为19世纪

调用函数后,原有数据不变,读week得出阴历BCD数据

*/

code uchar table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表

/*

算法:日期+年份+所过闰年数+月较正数之和除7 的余数就是星期但如果是在

闰年又不到3 月份上述之和要减一天再除7

星期数为0

*/

void Conver_week(bit c,uchar year,uchar month,uchar day)

{//c=0 为21世纪,c=1 为19世纪输入输出数据均为BCD数据

uchar temp1,temp2;

temp1=year/16; //BCD->hex 先把数据转换为十六进制

temp2=year%16;

year=temp1*10+temp2;

temp1=month/16;

temp2=month%16;

month=temp1*10+temp2;

temp1=day/16;

temp2=day%16;

day=temp1*10+temp2;

if (c==0){year+=0x64;} //如果为21世纪,年份数加100

temp1=year/0x4; //所过闰年数只算1900年之后的

temp2=year+temp1;

temp2=temp2%0x7; //为节省资源,先进行一次取余,避免数大于0xff,避免使用整型数据temp2=temp2+day+table_week[month-1];

if (year%0x4==0&&month<3)temp2-=1;

week=temp2%0x7;

}

//test

uchar c_sun,year_sun,month_sun,day_sun;

void main()

{

c_sun=1;

year_sun=0x2;

month_sun=0x11;

day_sun=0x3;

Conver_week(c_sun,year_sun,month_sun,day_sun);

Conversion(c_sun,year_sun,month_sun,day_sun);

while(1);

}

算法一:公历转农历

============================================================================ /*------------农历转换函数-----------*/

char *GetDayOf(PSYSTEMTIME pSt)

{

/*天干名称*/

const char *cTianGan[] = {"甲","乙","丙","丁","戊","己","庚","辛","壬","癸"};

/*地支名称*/

const char *cDiZhi[] = {"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"};

/*属相名称*/

const char *cShuXiang[] = {"鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"};

/*农历日期名*/

const char *cDayName[] = {"*","初一","初二","初三","初四","初五",

"初六","初七","初八","初九","初十","十一","十二","十三","十四","十五","十六","十","十八","十九","二十","廿一","廿二","廿三","廿四","廿五","廿六","廿七","廿八","廿九","三十"};

/*农历月份名*/

const char *cMonName[] = {"*","正","二","三","四","五","六","七","八","九","十","十一","腊"};

/*公历每月前面的天数*/

const int wMonthAdd[12] = {0,31,59,90,120,151,181,212,243,273,304,334};

/*农历数据*/

const int wNongliData[100] = {2635,333387,1701,1748,267701,694,2391,133423,1175,396438 ,3402,3749,331177,1453,694,201326,2350,465197,3221,3402

,400202,2901,1386,267611,605,2349,137515,2709,464533,1738

,2901,330421,1242,2651,199255,1323,529706,3733,1706,398762

,2741,1206,267438,2647,1318,204070,3477,461653,1386,2413

,330077,1197,2637,268877,3365,531109,2900,2922,398042,2395

,1179,267415,2635,661067,1701,1748,398772,2742,2391,330031

,1175,1611,200010,3749,527717,1452,2742,332397,2350,3222

,268949,3402,3493,133973,1386,464219,605,2349,334123,2709

,2890,267946,2773,592565,1210,2651,395863,1323,2707,265877};

static int wCurY ear,wCurMonth,wCurDay;

static int nTheDate,nIsEnd,m,k,n,i,nBit;

TCHAR szNongli[30], szNongliDay[10],szShuXiang[10];

/*---取当前公历年、月、日---*/

wCurY ear = pSt->wY ear;

wCurMonth = pSt->wMonth;

wCurDay = pSt->wDay;

/*---计算到初始时间1921年2月8日的天数:1921-2-8(正月初一)---*/

nTheDate = (wCurY ear - 1921) * 365 + (wCurY ear - 1921) / 4 + wCurDay + wMonthAdd[wCurMonth - 1] - 38;

if((!(wCurY ear % 4)) && (wCurMonth > 2))

nTheDate = nTheDate + 1;

/*--计算农历天干、地支、月、日---*/

nIsEnd = 0;

m = 0;

while(nIsEnd != 1)

{

if(wNongliData[m] < 4095)

k = 11;

else

k = 12;

n = k;

while(n>=0)

{

//获取wNongliData(m)的第n个二进制位的值

nBit = wNongliData[m];

for(i=1;i

nBit = nBit/2;

nBit = nBit % 2;

if (nTheDate <= (29 + nBit))

{

nIsEnd = 1;

break;

}

nTheDate = nTheDate - 29 - nBit;

n = n - 1;

}

if(nIsEnd)

break;

m = m + 1;

}

wCurY ear = 1921 + m;

wCurMonth = k - n + 1;

wCurDay = nTheDate;

if (k == 12)

{

if (wCurMonth == wNongliData[m] / 65536 + 1)

wCurMonth = 1 - wCurMonth;

else if (wCurMonth > wNongliData[m] / 65536 + 1)

wCurMonth = wCurMonth - 1;

}

/*--生成农历天干、地支、属相==> wNongli--*/

wsprintf(szShuXiang,"%s",cShuXiang[((wCurY ear - 4) % 60) % 12]);

wsprintf(szNongli,"%s(%s%s)年",szShuXiang,cTianGan[((wCurY ear - 4) % 60) % 10],cDiZhi[((wCurY ear - 4) % 60) % 12]);

/*--生成农历月、日==> wNongliDay--*/

if (wCurMonth < 1)

wsprintf(szNongliDay,"闰%s",cMonName[-1 * wCurMonth]);

else

strcpy(szNongliDay,cMonName[wCurMonth]);

strcat(szNongliDay,"月");

strcat(szNongliDay,cDayName[wCurDay]);

return strcat(szNongli,szNongliDay);

}

============================================================================

首先,我们要确定一个时刻,作为一天的起点(包括这个时刻)。然后我们以月亮通过朔望交界点的那一天作为每个月的第一天,以太阳通过雨水点的那个月作为正月,依次的,以太阳通过各中气点的那个月作为二月、三月等等。

经过长期的观察之后,我们就会发现每个月不是29天就是30天,每年不是12个月就是13个月,每个中气点唯一对应一个月,但是有的月却没有中气。

为了制定我们的历法,我们至少要知道足够精度的朔望月长度,记为ML,和两个中气的间隔时间记为YL,这两个值经过前人长期不懈的观测和计算,我们知道分别为29.5306日和30.4377日。接下来,我们要随便找到某一年,以太阳通过雨水点的时刻到那一年开始的那个时刻的时间,记为DY,以日为单位,还要找出这一年正月里,月亮通过朔望交界点的时刻到那一月开始的那个时刻的时间,记为DM,以日为单位。这两个值是要通过实地观测得出来的。

这个时候,我们就可以通过递推来制订我们的历法,以预测未来月球和太阳的运行情况,并进一步预测月相的变化和气候的变化。

在本算法中我们使用了三个近似处理:

每天的长度总是一样的;

每个朔望月的长度总是一样的;

每两个相邻中气的时间总是一样的。

接下来,我们就逐月推算每月的大小:

Select Case Fix(DM + ML)

Case is = 29

The month have 29 days.

The DM of next month is DM + ML - 29.

Case is = 30

The month have 30 days.

The DM of next month is DM + ML - 30.

End Select

每年中各月的月份、是否为闰月

For i = 1 to 12

This month has A days.

If DY>=A Then

This month is an Extra Month.

DY = DY - A

Else

This month is the i Month.

DY = DY + YL - A

i = i + 1

End If

Next

这就是我们的核心算法。通过它,我们可以从任何一个包含中气的月份开始向后推算各月各年的情况。

由于我们所用的DM、DY、ML、YL都是近似值,若干年后,我们的历法必有偏差,我们只要重新观测,更新DM、DY、ML、YL的值就可以了。事实上,诸朝气数最多不过400年,在这些值精确到万分位的时候,通行一朝是完全可以的。

下面对大小月的排列和闰月的出现作一些定性分析

显然0≤DM<1,那么

DM<0.4694时,当月为小月,下月为大月

DM≥0.4694时,当月为大月

DM<0.4694 * 2时,下月为小月,下下月为大月

DM≥0.4694 * 2时,下月亦为大月,下下月为小月

所以,大小月一般是交替出现,有时会出现连续两个月是大月的情况,但不会出现连续三个月或更多的是大月的情况,也不会出现连续两个月更多的是小月的情况。也就是说,一般是小月大月相继出现一段时间后,接着就出现一个大月,然后又是小月大月相继出现,具体的间隔也不定,大家可以通过计算机推算后,找点规律出来。

一年中最少有十二个月,因为YL * 12 (代表十二个中气循环一次的时间)>ML * 12 (代表十二个朔望月的时间)+ 1 (第一个月的DM总小于1),最多有十三个月,因为30(第一个月的DY 总小于30)+ YL * 12 <ML * 14。两个相邻中气的间隔时间大于30,所以一个月不可能有两个中气,那么一年有十二个月的时候,12个中气必然刚好依次各居一个月,这一年就称为平年,一年有十三个月的时候,必然有且仅有一个月没有中气,那个月就时闰月,这一年就称为闰年。平年的时候,根据大小月的排列规则,一年最多有8个大月,最少有6个大月,因为ML * 12 + 1 <30 * 8 + 29 * (12 - 8),所以不可能有8个大月,最多为7个大月,那么一年就为354或355天。闰年的时候,根据大小月的排列规则,一年最多有9个大月,最少有6个大月,因为ML * 13 + 1 <30 * 8 + 29 * (13 - 8),所以不可能有8个或更多的大月,最多为7个大月,那么一年就为383或384天。

因为每月的天数不固定,所以闰月的出现规律也不好讨论,连续十二个月的天数也不固定,所以闰年的出现规律也不好讨论。不过可以肯定是,每年的第一个月肯定不是闰月,因为我们是以包含中气雨水的月份作为正月,也就是每年的第一个月的。所以,闰月必定出现在某个有名字的月份后面,出现在哪个后面就叫闰哪月。

由于有闰月,所以函数形式:

int toSolar(int ly, int lm, int ld, int *sy, int *sm, int *sd, int *sy2, int *sm2, int *sd2);

引理:公历y-m-d一定在农历y-m-d之前

由引理,我们的探测可以从公历y-m-d开始,步骤如下:

1)toLunar(y, m, d, &ly0, &lm0, &ld0);

2)估算ly0-lm0-ld0和ly-lm-ld的日子差N = (ly-ly0)*12*29 + (lm-lm0)*29 + (ld-ld0);

3)如果N > 0,把探测公历y-m-d加上这个天数,dateAddDays(&y, &m, &d, N);

4)如果N = 0,如果(ly==ly0)&&(lm==lm0)&&(ld==ld0)得到一个解sy=y;sm=m;sd=d; (如果此时sy已经被赋值过,则sy2=y;sm2=m;sd2=d;返回退出)

否则表示出现误差,修正N = 1;dateAddDays(&y, &m, &d, N);

从而开始探测闰月,令N = 30;dateAddDays(&y, &m, &d, N);

5)如果N < 0,且N >= -30,肯定是上次探测N+29不够(该月大),应该+30,

所以令N = 1; dateAddDays(&y, &m, &d, N);

经过测试,最多需要3次可以命中,还是比较理想的算法了:)

PS:经过完全测试,公元1500-2100年没有问,最多尝试次数为3次

#define LUNAR_TO_SOLAR_STEPS 3 // 公历转公历搜索最长步数

// 农历返回公历

// 注意:这是我在掌心万年历中写的代码,版权属于我所有,仅供个人学习使用,严禁在任何商业软件中使用本代码

// 输入农历年-月-日ly-lm-ld (lm < 0表示闰月)

// 输出公历年-月-日y-m-d

/*

公元1500年前的情况太特殊,比如公元9-1月,缺少农历11月,直接导致计算ldiff错误...

所以toSolar只支持1500年以后的转换. --ZV

*/

int toSolar(int LunarY ear, int LunarMonth, int LunarDay)

{

if (LunarY ear < 1500) { // 非常复杂的问题

return CALENDAR_ERROR;

}

int ret;

int y = LunarY ear;

int m = abs(LunarMonth);

int d = LunarDay;

int i, ldiff = 0, lunDate;

int ly, lm, ld;

validateDate(&y, &m, &d);

for (i = 0; i < LUNAR_TO_SOLAR_STEPS; i++) {

lunDate = toLunar(y, m, d);

DA TE_TO_YMD(lunDate, ly, lm, ld);

if (abs(lm) == abs(LunarMonth) && ld == LunarDay) {

if (lm == LunarMonth) {

ret = YMD_TO_DA TE(y, m, d);

return ret;

}

// 如果找到一个,则开始探测闰月

ldiff = 30; // 要么直接转到,要么多了一天而已

} else {

ldiff = (LunarY ear - ly) * 12 * 29 + (abs(LunarMonth) - abs(lm)) * 29 + (LunarDay - ld);

if (ldiff == 0) { // 稍做修正

ldiff = 1;

}

}

dateAddDays(&y, &m, &d, ldiff); // 注意可能出现负数}

return CALENDAR_ERROR;

}

阳历转化成农历法

阳历转化成农历法

————————————————————————————————作者:————————————————————————————————日期:

c++中怎样将阳历转化成农历 已关闭20[ 标签:c++, 阳历, 农历 ] 小^鱼、2011-05-03 11:06 推荐答案 一、原理篇 1.公历转换农历的算法 公历(Gregorian Calendar)与农历(Chinese Lunar Calendar)的转换关系不是一个简单的公式就可以完成,其中的转换比较复杂,原因是农历的制定相当复杂,是根据天文观测进行指定的。 比较常用并且比较简单的公历转换农历算法就是查表方法。首先要保存公历农历的转换信息:以任何一年作为起点,把从这一年起若干年的农历信息保存起来(在我的C++类中,是从1900年作为起点的。选择一个起始点的思想十分重要,在下面的干支纪法和二十四节气中也体现到了)。回想一下,我们平时是怎样来转换公历农历的呢?是查阅历书,历书中有每一天的公历农历,直接一查就可以了。那么我们可不可以也这样做呢?当然可以,但是这样做要收录每一天的信息,工作量就会很大,所以我们要简化这些信息。如何简化呢? 要保存一年的信息,其实只要两个信息就可以了:(1)农历每个月的大小;(2)今年是否有闰月,闰几月以及闰月的大小。用一个整数来保存这些信息就足够了。具体的方法是:用一位来表示一个月的大小,大月记为1,小月记为0,这样就用掉了12位,再用低四位来表示闰月的月份,没有闰月记为0。比如说,2000年的信息数据是0x0c960,转化成二进制就是1100100101100000,表示的含义是1、2、5、8、10、11月大,其余月小,低四位为0说明没有闰月。2001年的农历信息数据是0x0d954,其中的4表示该年闰4月,月份大小信息就是0x0d95,具体的就是1、2、4、5、8、10、12月大,其余月小。这样就可以用一个数组来保存这些信息。在我的C++类中是用m_lunarInfo这个数组来保存这些信息的。 下面就是公历转换成农历的具体算法: (1)计算所求时间到起始年正月初一的天数。 (2)从起始年份开始,减去每一月的天数,一直到剩余天数没有下一个月多为止。此时,m_lunarInfo的下标到了多少,就是减去了多少年,用起始年份加上这个下标就可以得到农历年份,然后看减去了几个月。如果本年不闰月或者闰月还在后面,就可以直接得到农历月份,如果在闰月月份数后面一个月,则这个月就是闰月。剩余的天数就是农历日。(具体实现时有所改进。) 2.利于泰勒公式巧算星期 在应用数学中有一个计算某一天是星期几的公式,这就是泰勒公式。公式如下: w = [c÷4] - 2c + y + [y÷4] + [26(m+1)÷10] + d - 1,其中w就是所求日期的星期数。如果求得的数大于(小于)7,就减去(加上)7的倍数,直到余数小于7为止。式子中c是指公

公历和农历之间如何转换

公历和农历之间如何转换? 很多人都一直在找换阴阳历的公式。我也尝试过。曾读过「高平子」天文前辈所着「学历散论」了解古历的变更和阴阳历的缺陷。才知道由於月球转动的不稳定不规则,确定无公式可寻。这也是古代中国每百年必改历的原因。 阴历最大的问题是在如何置闰。好像不难,因为阴历基本法则如下: * 月朔日即是初一 * 月以中气得名 * 以包含雨水中气月为正月,即是「寅」月 * 月无中气者为闰月,以前月同名 如果,日月转动循还有规则的话,推演一套阴阳历转换的公式并不难。问题在有时一个太阴月比一个太阳月还要长。如此一个太阴月就有可能包括两个中气。此双中气月後的阴历月名就全部乱掉了,直到下一个「假」闰月後才调整过来。 一般人接触到的阴阳历是民用历法,它是政府颁令的以东经120度计算的历法或称中原标准时间或北京时。如果,我们用不同时区、不同经度为子午线来重新计算阴阳历,民用历法的置闰法则出了很大的问题。不同时区的闰月可能落在不同月。换言之,在一百年内,任何两个时区的闰月顺序模式是会不相同的。 高平子前辈书中提到了「历理置闰法」。如果应用历理置闰法到不同时区,则所有不同时区的闰月都落在相同月。如此不同时区、不同经度的阴

阳历置闰之问题就消失了。民用置闰和历理置闰的不同是: * 在民用置闰,如果月朔日和中气同一天,则该阴历月包含那个中气。 * 在历理置闰,如果月朔日和中气同一天,月朔日时间必须在中气时间之前,则该阴历月才包含那个中气。 简言之,民用置闰比较月朔和中气日期;历理置闰比较月朔和中气日期、时、分、秒。由此可知,没有精确的太阳和月亮的时间数字,阴历的闰月可能会排错了。 基於这些理由,我着手寻找天文公式计算精确的太阳和月亮在纬度的时间。当年没有网路,发了大半年於美国南加州各大图书馆及大学,找寻答案。1993年出版了「中美天文万年历」一书。书中精确的天文日月时间只从1900到2010年。因恐2011後时间误差超过一分钟,不够精确,不敢印出。今年2002从网路资讯,确定太阳和月亮时间的精确度後,百忙中重新整理资料,提供给需要阴阳历转换公式的朋友。 整理出的太阳和月亮时间数字是从西元1年到2246年。有历理和中国民用两套历法。数字内容清清楚楚的看出民用历法的敝端。例如,从西元1600年到2246年,民用历法双中气的阴历月有22个,历理历法只有5个。民用历法甚至在2033、2128和2242年中,三个月之间居然跑出两个双中气;换言之,三个月中多出两个「假」闰月。前後12个阴历月中有三个闰月,闰月的去留造成许多学者的讨论和困恼。历理历法在此三年中,却没有发现到双中气阴历月。闰月的去留只要把双中气月後的「假」闰月取消,则历理历法近乎於完美。 由此可知,民用历法问题很大,应该废除。上次阴阳历重大改历在1645

公历和农历转换算法详解

公历和农历转换算法详解 //C51写的公历转农历和星期 #define uchar unsigned char #define uint unsigned int #include /* 公历年对应的农历数据,每年三字节, 格式第一字节BIT7-4 位表示闰月月份,值为0 为无闰月,BIT3-0 对应农历第1-4 月的大小第二字节BIT7-0 对应农历第5-12 月大小,第三字节BIT7 表示农历第13 个月大小 月份对应的位为1 表示本农历月大(30 天),为0 表示小(29 天) 第三字节BIT6-5 表示春节的公历月份,BIT4-0 表示春节的公历日期 */ code uchar year_code[597] = { 0x04,0xAe,0x53, //1901 0 0x0A,0x57,0x48, //1902 3 0x55,0x26,0xBd, //1903 6 0x0d,0x26,0x50, //1904 9 0x0d,0x95,0x44, //1905 12 0x46,0xAA,0xB9, //1906 15 0x05,0x6A,0x4d, //1907 18 0x09,0xAd,0x42, //1908 21 0x24,0xAe,0xB6, //1909 0x04,0xAe,0x4A, //1910 0x6A,0x4d,0xBe, //1911 0x0A,0x4d,0x52, //1912 0x0d,0x25,0x46, //1913 0x5d,0x52,0xBA, //1914 0x0B,0x54,0x4e, //1915 0x0d,0x6A,0x43, //1916 0x29,0x6d,0x37, //1917 0x09,0x5B,0x4B, //1918 0x74,0x9B,0xC1, //1919 0x04,0x97,0x54, //1920 0x0A,0x4B,0x48, //1921 0x5B,0x25,0xBC, //1922 0x06,0xA5,0x50, //1923 0x06,0xd4,0x45, //1924 0x4A,0xdA,0xB8, //1925 0x02,0xB6,0x4d, //1926 0x09,0x57,0x42, //1927 0x24,0x97,0xB7, //1928

公历转农历EXCEL宏讲解

Public Function NongLi(Optional XX_DATE As Date) Dim MonthAdd(11), NongliData(99), TianGan(9), DiZhi(11), ShuXiang(11), DayName(30), MonName(12) Dim curTime, curYear, curMonth, curDay Dim GongliStr, NongliStr, NongliDayStr Dim i, m, n, k, isEnd, bit, TheDate '??è?μ±?°?μí3ê±?? curTime = XX_DATE 'ìì?é??3? TianGan(0) = "?×" TianGan(1) = "òò" TianGan(2) = "±?" TianGan(3) = "??" TianGan(4) = "?ì" TianGan(5) = "?o" TianGan(6) = "?y" TianGan(7) = "Dá" TianGan(8) = "èé" TianGan(9) = "1?" 'μ??§??3? DiZhi(0) = "×ó" DiZhi(1) = "3ó" DiZhi(2) = "òú" DiZhi(3) = "??" DiZhi(4) = "3?" DiZhi(5) = "?è" DiZhi(6) = "??" DiZhi(7) = "?′" DiZhi(8) = "éê" DiZhi(9) = "ó?" DiZhi(10) = "D?" DiZhi(11) = "o¥" 'ê??à??3? ShuXiang(0) = "êó" ShuXiang(1) = "?£" ShuXiang(2) = "?¢" ShuXiang(3) = "í?" ShuXiang(4) = "áú" ShuXiang(5) = "é?" ShuXiang(6) = "?í"

阴历阳历转换计算公式

1、阳历日期推算阴历日期的方法: 前已述及阴历日期是以月亮的圆缺为计月单位,其以逢朔为初一,以月望为十五(大月 为十六日),以月晦为二十九日(大月为三十日)。 如要知道1984年6月8日是阴历几日?可以利用公式推算阴历日期: 设:公元年数-1977(或1901)=4Q+R 则:阴历日期=14Q+10.6(R+1)+年内日期序数-29.5n (注:式中Q、R、n均为自然数,R<4) 例:1994年5月7日的阴历日期为: 1994-1977=17=4×4+1 故:Q=4,R=1 则:5月7日的阴历日期为: 14×4+10.6(1+1)+(31+28+31+31+7)-29.5n =204.2- 29.5n 然后用29.5去除204.2得商数 6......27.2,6即是n值,余数27即是阴历二十七日2.公历换算为农历 二十四节气在黄道上的位置是固定的,但各年有平年和闰年之分,就使得回归年天数与 实际天数不等,每年在日历上可差一天。这样可以将阴历经过任意整回归年在现在的日历上 查到阳历(阳历一年相当阴历的月数为365.2422/29.530588=12.36827个月)。例如,可先在1995年的日历上查得与(该年)阴历对应的阳历日期,这样就找到了临时落脚点, 也就是找到了阴阳互换的关键。例如,可先以阴历四月初一(日)为引数,在1995年日历上查到对应的阳历为4月30日。由于已经计算出经过的月数,将经过的月数的尾数(小数)化为日,加在4月30日上,就得到经过(1995-1070)整年数的阳历日期,也就是起始阴 历日期对应的阳历日期,即得到了待查的日期为4月30日加上0.64957×29.530588得到(1070年)5月19.1821840日。这样就得到了所给例子的阴阳历日期换算结果……”。 0.64957月的由来, (1995-1070)×12.36827=11440.64957月 已知依泽公生于梁龙德二年(922)六月二十一日,依下表提供的2099年各月初一日的公历月日数,可以算出龙德二年六月二十一日的公历月日数 公元2099年农历各月初一日的公历月日 (2099-922)×12.36827=1455.45379月 余数为0.45379月×29.530588日=13.4O日 因2099年五月初一日(包括该年闯二月)在公历6月19日,加上计算所得的13日为龙德二年六月初一日的公历月日,即该年7月2日,则该年农历六月二十一日为该年7月22日。 3.计算结果的订正 实际上上列公历换算为农历时常有较大的误差,如熙宁三年四月初一日为公历1070年5月13日,而不是5月19日。通过中国历法所用的于支记日法求算所用两历的干支,对所 求结果加以订正。 如,马依泽公生于回历310年3月20日,自回历历元起算共历日数为: 自回历元旦至其3月20日,共历79日。 自回历元年元旦至309年元旦,共历113个闰年196个平年。又回历历元在公历622年7月16日,已知该日的干支序数为50,癸丑日,减1(因自甲子起算),余49应加入下列算式中, (309 ×354+113+79+49)÷60=1827.116667

excel公历转农历的四种方法

excel公历转农历的四种方法 excel公历转农历方法一:使用text函数 A列是公历日期,我们在B1单元格输入公式:=TEXT(A1,"[$-130000]yyyy年m月"&I F(LEN(--TEXT(A1,"[$-130000]dd"))=1,"初","")&"d"),下拉完成公历转农历。 excel公历转农历方法二:使用text+MID函数 A列仍然是公历,B1输入公式:=MID("甲乙丙丁戊己庚辛壬癸",MOD(TEXT(A1,"[$-13 0000]e")-4,10)+1,1)&MID("子丑寅卯辰巳午未申酉戌亥",MOD(TEXT(A1,"[$-130000]e")-4, 12)+1,1)&"年"&TEXT(A1,"[$-130000][DBNum1]m月d日"即可。 excel公历转农历方法三:使用text+MID+ CHOOSE+ YEAR函数 A1为公历,B1输入:=CHOOSE(MOD(YEAR(A1)-1900,10)+1,"庚","辛","壬","癸","甲", "乙","丙","丁","戊","己")&CHOOSE(MOD(YEAR(A1)-1900,12)+1,"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥")&TEXT(A1,"[dbnum1][$-130000]年m月"&IF(--TEXT(A1, "[$-130000]d")<11,"初","")&TEXT(A1,"[dbnum1][$-130000]d")) excel公历转农历方法四:使用自定义函数 上面介绍的excel公历转农历都是使用excel内置函数完成的,有一个弊端就是公式太长,如果使用自定义函数,在公式栏就可以简化输入。 如下图所示,我们在B2输入公式:=nongli(A2),即可。C列农历简称中C2公式是:=RIGHT(B2,LEN(B2)-8)。

回历、公历、农历的换算

回历、公历、农历的换算 2002-2-10 22:02:19 马肇曾阅读9061次 研究世界伊斯兰教历史,免不了要对以回历所记载的历史事实换算为公历,或将所载的公历换算为回历。《回历纲要》、《历法丛谈》、《万年历谱》以及《回回天文学史研究》[1--4]等专著都载有自回历换算为公历的算式,并称两历因闰年的时间不同,故换算结果常有一日之差,惟均未讨论一日之差的简易订正方法。1998年《北京大学学报》(自然科学版)载文讨论了中国农历与公历、回历的换算问题[5]。惟笔者依上列著作中所列算式推算结果;发现与实际所载日期误差常大于一日,最高可达十日之多。因此有必要对计算中误差的来源及计算公式的改进进行探讨,特撰此文。 二、国历换算为公历 1.换算公式的导出 公历每年365.242 199074075 日(简化为365.2422日),而回历每年为354.367074375日(简化为354.36707日),所以回历一年只相当354.36707/365.2422=0.970223或0.970224个公历年。又回历元年元旦定在公元622年7月16日,由于当时历法在推算上的误差,致当时的7月16日,按现代的公历应改为7月19日,自公元某年元旦至该年7月19日已达200日.相200/365.2422=0.5476公历年;又因到回历二年元旦才达到0.970224个公历年,故自回历纪年元旦换算为公历的算式即为: (回历纪年一1)× 0.970224+622.5476年 =所求公历年月日 (1) 或回历纪年× 0.970224+621.5774年 =所求公历年月日 (2) 式中621.5774来自622.5476-0.970224。 如所求某一历史事实不在回历元旦时,可将事实经过本年的总日数化为回历年,加人回历纪年总数中即可。 然而上列公历一年的总日数,实际上是一回归年的实测数,因现用公历每年的日数实为365.2425日,它与一回归年的日数只能是基本相符,到公元四千多年后会再出现一日之差。 实际上在明万历十年九月十八日,回历990年9月16日,公元1582年10月4日前(包括4日)的公历称儒略历,儒略历每年365.25日,它每年与一回归年的差值远大于格列高利历即现代的公历,大约历128年就需多闰去一日,至万历十年已经多闰出十日了。因此,对于儒略历时期的回、公两历换算,不能仍采用(l)、(2)两式,而需依儒略历的年实际日数将上列二式略加修正即可,结果如下: (回历纪年一l)× 0.9702+622.5393 = 所求公历年月日 (3)

阳历转化成农历算法

c++中怎样将阳历转化成农历 已关闭20[ 标签:c++, 阳历, 农历 ] 小^鱼、2011-05-03 11:06 推荐答案 一、原理篇 1.公历转换农历的算法 公历(Gregorian Calendar)与农历(Chinese Lunar Calendar)的转换关系不是一个简单的公式就可以完成,其中的转换比较复杂,原因是农历的制定相当复杂,是根据天文观测进行指定的。 比较常用并且比较简单的公历转换农历算法就是查表方法。首先要保存公历农历的转换信息:以任何一年作为起点,把从这一年起若干年的农历信息保存起来(在我的C++类中,是从1900年作为起点的。选择一个起始点的思想十分重要,在下面的干支纪法和二十四节气中也体现到了)。回想一下,我们平时是怎样来转换公历农历的呢?是查阅历书,历书中有每一天的公历农历,直接一查就可以了。那么我们可不可以也这样做呢?当然可以,但是这样做要收录每一天的信息,工作量就会很大,所以我们要简化这些信息。如何简化呢? 要保存一年的信息,其实只要两个信息就可以了:(1)农历每个月的大小;(2)今年是否有闰月,闰几月以及闰月的大小。用一个整数来保存这些信息就足够了。具体的方法是:用一位来表示一个月的大小,大月记为1,小月记为0,这样就用掉了12位,再用低四位来表示闰月的月份,没有闰月记为0。比如说,2000年的信息数据是0x0c960,转化成二进制就是1100100101100000,表示的含义是1、2、5、8、10、11月大,其余月小,低四位为0说明没有闰月。2001年的农历信息数据是0x0d954,其中的4表示该年闰4月,月份大小信息就是0x0d95,具体的就是1、2、4、5、8、10、12月大,其余月小。这样就可以用一个数组来保存这些信息。在我的C++类中是用m_lunarInfo这个数组来保存这些信息的。 下面就是公历转换成农历的具体算法: (1)计算所求时间到起始年正月初一的天数。 (2)从起始年份开始,减去每一月的天数,一直到剩余天数没有下一个月多为止。此时,m_lunarInfo的下标到了多少,就是减去了多少年,用起始年份加上这个下标就可以得到农历年份,然后看减去了几个月。如果本年不闰月或者闰月还在后面,就可以直接得到农历月份,如果在闰月月份数后面一个月,则这个月就是闰月。剩余的天数就是农历日。(具体实现时有所改进。) 2.利于泰勒公式巧算星期 在应用数学中有一个计算某一天是星期几的公式,这就是泰勒公式。公式如下: w = [c÷4] - 2c + y + [y÷4] + [26(m+1)÷10] + d - 1,其中w就是所求日期的星期数。如果求得的数大于(小于)7,就减去(加上)7的倍数,直到余数小于7为止。式子中c是指公

公元与农历的换算方法

公元与农历的换算方法 一、记住农历的天干和地支的顺序 天干顺序:甲、乙、丙、丁、戊、己、庚、辛、壬、癸。 地支顺序:子、丑、寅、卯、辰、巳、午、未、申、酉、戍、亥。 二、掌握天干和地支的搭配方法KCB齿轮泵 年数从甲子、乙丑、丙寅、丁卯、戊辰、己巳、庚午、辛未、癸酉;后继续甲戍、乙亥、丙子……,60年时刚好是葵亥。每个干支为一年,六十个干支后,又从头算起2CY系列齿轮泵,周而复始,循环不息。由甲子开始,满六十年称做一甲子或一花甲子,称为干支纪年法。搭配时先天干后地支。 三、使用如下公式KCB不锈钢齿轮泵 1、天干计算公式:(公元年代—3)/10.整除时是葵,余数1、 2、 3、 4、 5、 6、 7、 8、9分别是甲、乙、丙、丁、戊、己、庚、辛、壬(按顺序)。LYB系列立式液下齿轮泵 2、地支计算公式:(公元年代—3)/12.整除时是亥,余数1、2、 3、4、5、6、7、8、9、10、11分别是子、丑、寅、卯、辰、巳、午、未、申、酉、戍(按顺序)KCB-T铜齿轮泵。 如:1894年甲午中**战争 (1894—3)/10 余数是1,GZYB高精度齿轮泵天干属于“甲”;(1894—3)/12 余数是7,地支属于“午”。再把天干和地支合起来就是“甲午”。KCB系列大流量齿轮泵 又如:1898年戊戌变法

(1898—3)/10 余数是5,KCB齿轮泵安装尺寸天干属于“戊”;(1898—3)/12 余数是11,地支属于“戌”。再把天干和地支合起来就是“戊戌”。2CY齿轮泵安装尺寸 再如:1911年辛亥革命 (1911—3)/10 余数是8,天干属于“辛”;(1911—3)/12 结果是整除,地支属于“亥”。高压齿轮泵再把天干和地支合起来就是“辛亥”。

阳历与阴历的转换

public class Date2 { //天干 private static string[] TianGan = { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" }; //地支 private static string[] DiZhi = { "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" }; //十二生肖 private static string[] ShengXiao = { "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" }; //农历日期 private static string[] DayName = {"*","初一","初二","初三","初四","初五", "初六","初七","初八","初九","初十", "十一","十二","十三","十四","十五", "十六","十七","十八","十九","二十", "廿一","廿二","廿三","廿四","廿五", "廿六","廿七","廿八","廿九","三十"}; //农历月份 private static string[] MonthName = { "*", "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "腊" }; //公历月计数天 private static int[] MonthAdd = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; //农历数据 private static int[] LunarData = {2635,333387,1701,1748,267701,694,2391,133423,1175,396438 ,3402,3749,331177,1453,694,201326,2350,465197,3221,3402 ,400202,2901,1386,267611,605,2349,137515,2709,464533,1738 ,2901,330421,1242,2651,199255,1323,529706,3733,1706,398762 ,2741,1206,267438,2647,1318,204070,3477,461653,1386,2413 ,330077,1197,2637,268877,3365,531109,2900,2922,398042,2395 ,1179,267415,2635,661067,1701,1748,398772,2742,2391,330031 ,1175,1611,200010,3749,527717,1452,2742,332397,2350,3222 ,268949,3402,3493,133973,1386,464219,605,2349,334123,2709 ,2890,267946,2773,592565,1210,2651,395863,1323,2707,265877};

公历转农历方法

阳历日期推算阴历日期的方法:前已述及阴历日期是以月亮的圆缺为计月单位,其以逢朔为初一,以月望为十五(大月为十六日),以月晦为二十九日(大月为三十日)。然而目前记时通常用阳历日期表达,如欲将阳历日期换算成阴历日期可以用以下两种方法:其一是查《新编万年历》,如查1984年6月8日是阴历几日?翻开万年历6月10日是阴历十一,则逆推6月8日是阴历初九。其二可以利用公式推算阴历日期: 设:公元年数-1977(或1901)=4q+r 则:阴历日期=14q+10.6(r+1)+年内日期序数-29.5n (注:式中q、r、n均为自然数,r<4) 例:1994年5月7日的阴历日期为: 1994-1977=17=4×4+1 故:q=4,r=1 则:5月7日的阴历日期为: 14×4+10.6(1+1)+(31+28+31+31+7)-29.5n =204.2- 29.5n 然后用29.5去除204.2得商数6......27.2,6即是n值,余数27即是阴历二十七日。 蔡勒(Zeller)公式:是一个计算星期的公式。 随便给一个日期,就能用这个公式推算出是星期几。 蔡勒公式如下: W = [ C/4 ] - 2C + y + [ y/4 ] + [ 13 * (M + 1) / 5] + d -1 公式中的符号含义如下: W: 星期;w对7取模得:0-星期日,1-星期一,2-星期二,3-星期三,4-星期四,5-星期五,6-星期六 C: 世纪-1(前两位数) y: 年(后两位数) m: 月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月来计算,比如2003年1月1日要看作2002年的13月1日来计算) d: 日 [ ]代表取整,即只要整数部分。 下面以中华人民共和国成立100周年纪念日那天(2049年10月1日)来计算是星期几,过程如下: w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1 =49+[49/4]+[20/4]-2×20+[26×(10+1)/10]+1-1 =49+[12.25]+5-40+[28.6] =49+12+5-40+28 =54 (除以7余5) 即2049年10月1日(100周年国庆)是星期五。 再比如计算2006年4月4日,过程如下: w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1 =6+[6/4]+[20/4]-2*20+[26*(4+1)/10]+4-1 =-12 (除以7余2,注意对负数的取模运算!) 不过,以上的公式都只适合于1582年(我国明朝万历十年)10月15日之后的情形。罗

公历转农历(a版本)

公历转农历(A版本) Tags:版本wCurMonth wCurYear if农历nTheDate nBit const公历转农历(C 版本) PHP开发环境的选择、建立及使用[8]编写自定义任务,轻松扩展Ant(2)代联接的自定义右键菜单面试中如何体现身价希特勒生日(4月20日)突破生命中那条线怎么用ado打开带密码的access数据库算法复杂度攻击激烈讨论在Visual https://www.sodocs.net/doc/0811290874.html,中使用自定义插公历转农历(C版本)版本wCurMonth wCurYear if农历nTheDate nBit const 前段时间做软件写了个公历转农历的函数,目前公开给大家参考,有兴趣的朋友可以在此基础上进一步完善其功能 /*------------农历转换函数-----------*/ char *GetDayOf(PSYSTEMTIME pSt) { /*天干名称*/ const char *cTianGan[] = {"甲","乙","丙","丁","戊","己","庚","辛","壬","癸"}; /*地支名称*/ const char *cDiZhi[] = {"子","丑","寅","卯","辰","巳","午", "未","申","酉","戌","亥"}; /*属相名称*/ const char *cShuXiang[] = {"鼠","牛","虎","兔","龙","蛇", "马","羊","猴","鸡","狗","猪"}; /*农历日期名*/ const char *cDayName[] = {"*","初一","初二","初三","初四","初五", "初六","初七","初八","初九","初十",

采用查表的方法实现农历与公历的转换)

采用查表的方法实现农历与公历的转换,可以坚持50年,50年以后可以补充表继续使用,当然50年以后什么样子都不知道,这个方法可能早淘汰了。哈哈! #define uchar unsigned char #define uint unsigned int #include /* 公历年对应的农历数据,每年三字节, 格式第一字节BIT7-4 位表示闰月月份,值为0 为无闰月,BIT3-0 对应农历第1-4 月的大小第二字节BIT7-0 对应农历第5-12 月大小,第三字节BIT7 表示农历第13 个月大小 月份对应的位为1 表示本农历月大(30 天),为0 表示小(29 天) 第三字节BIT6-5 表示春节的公历月份,BIT4-0 表示春节的公历日期 */ code uchar year_code[597]={ 0x04,0xAe,0x53, //1901 0 0x0A,0x57,0x48, //1902 3 0x55,0x26,0xBd, //1903 6 0x0d,0x26,0x50, //1904 9 0x0d,0x95,0x44, //1905 12 0x46,0xAA,0xB9, //1906 15 0x05,0x6A,0x4d, //1907 18 0x09,0xAd,0x42, //1908 21 0x24,0xAe,0xB6, //1909 0x04,0xAe,0x4A, //1910 0x6A,0x4d,0xBe, //1911 0x0A,0x4d,0x52, //1912 0x0d,0x25,0x46, //1913 0x5d,0x52,0xBA, //1914 0x0B,0x54,0x4e, //1915 0x0d,0x6A,0x43, //1916 0x29,0x6d,0x37, //1917 0x09,0x5B,0x4B, //1918 0x74,0x9B,0xC1, //1919 0x04,0x97,0x54, //1920 0x0A,0x4B,0x48, //1921 0x5B,0x25,0xBC, //1922 0x06,0xA5,0x50, //1923 0x06,0xd4,0x45, //1924 0x4A,0xdA,0xB8, //1925 0x02,0xB6,0x4d, //1926 0x09,0x57,0x42, //1927 0x24,0x97,0xB7, //1928 0x04,0x97,0x4A, //1929 0x66,0x4B,0x3e, //1930

Excel公历转农历阳历转阴历

参看一: 可以这样试一下:EXCEL2007中可以直接做到,例如 TEXT(日期,"[$-130000]e-m-d"),可返回日期的阿拉伯数字的农历年月日, 中文农历转换公式如下: B2单元格 =MID("庚辛壬癸甲乙丙丁戊己",MOD(TEXT(A2,"[$-130000]e"),10)+1,1)&MID("申酉戌亥子丑寅卯辰巳午未",MOD(TEXT(A2,"[$-130000]e"),12)+1,1)&TEXT(A2,"[dbnum1][$-130000]年M月 "&IF(-TEXT(A2,"[$-130000]d")<-10,,"初")&"D日") 此公式仅EXCEL2007以使用,EXCEL2003及以下不能正常使用 上面那个公式好像有问题,可以试一下这个: 参看二: 日期在A2, 这个公式在B2 =CHOOSE(MOD(YEAR(LEFT(TEXT(A2,"[$-130000]yyyy年mm月"&IF(LEN(--TEXT(A2,"[$-130000]dd"))=1,"初","")&"dd"),4)&"-"&MID(TEXT(A2,"[$-130000]yyyy年mm月"&IF(LEN(--TEXT(A2,"[$-130000]dd"))=1,"初","")&"dd"),6,2)&"-"&RIGHT(TEXT(A2,"[$-130000]yyyy年mm月"&IF(LEN(--TEXT(A2,"[$-130000]dd"))=1,"初","")&"dd"),2))-1900,10)+1,"庚","辛","壬","癸","甲","乙","丙","丁","戊","己 ")&CHOOSE(MOD(YEAR(LEFT(TEXT(A2,"[$-130000]yyyy年mm月"&IF(LEN(--TEXT(A2,"[$-130000]dd"))=1,"初","")&"dd"),4)&"-"&MID(TEXT(A2,"[$-130000]yyyy年mm月"&IF(LEN(--TEXT(A2,"[$-130000]dd"))=1,"初","")&"dd"),6,2)&"-"&RIGHT(TEXT(A2,"[$-130000]yyyy年mm月"&IF(LEN(--TEXT(A2,"[$-130000]dd"))=1,"初","")&"dd"),2))-1900,12)+1,"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥 ")&TEXT(A2,"[dbnum1][$-130000]年m月"&IF(--TEXT(A2,"[$-130000]d")<11,"初 ","")&TEXT(A2,"[dbnum1][$-130000]d日")) =CHOOSE(MOD(YEAR(LEFT(TEXT(A11,"[$-130000]yyyy年mm月" &IF(LEN(--TEXT(A11,"[$-130000]dd"))=1,"初","") &"dd"),4) &"-"&MID(TEXT(A11,"[$-130000]yyyy年mm月" &IF(LEN(--TEXT(A11,"[$-130000]dd"))=1,"初","") &"dd"),6,2) &"-"&RIGHT(TEXT(A11,"[$-130000]yyyy年mm月" &IF(LEN(--TEXT(A11,"[$-130000]dd"))=1,"初","") &"dd"),2))-1900,10)+1,"庚","辛","壬","癸","甲","乙","丙","丁","戊","己") &CHOOSE(MOD(YEAR(LEFT(TEXT(A11,"[$-130000]yyyy年mm月" &IF(LEN(--TEXT(A11,"[$-130000]dd"))=1,"初","") &"dd"),4)&"-" &MID(TEXT(A11,"[$-130000]yyyy年mm月" &IF(LEN(--TEXT(A11,"[$-130000]dd"))=1,"初","") &"dd"),6,2) &"-" &RIGHT(TEXT(A11,"[$-130000]yyyy年mm月" &IF(LEN(--TEXT(A11,"[$-130000]dd"))=1,"初","") &"dd"),2))-1900,12)+1,"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥")

公历转换为农历的算法

公历转换为农历的算法: 0101000101111 前12为代表大小月,第13位代表闰月的大小月 6 代表闰月的月份 0 代表无闰月 64311 代表当年春节的公历日期 1.首先获取当前日期。S time=+$h 2.判断查询日期是否在春节之前。如果是取上一年的信息。否则取当前年的信息为 农历年 3. 4.判断当前日期和最近的春节相差的天数。 Days 5.如果没有闰月,判断前12位的大小月, 如果是大月 ,则相差天数-30 如果是小月则相差天数-29,直到相差天数在30 或者 29天内。 取当前的月份,即农历的月份,天数+1 即为农历的天。 如果有闰月,判断前13位的大小月,判断方法和前面的类似,只是到闰月的月份时,需要在前面增加一个闰字。 /// gl 23/06/2016格式 gldays数字形式的日期 /// w ##class(websys.CalendarUtil).ToLuner("01/01/2017") /// @param: gl 公历日期格式 DD/MM/YYYY /// @return: 返回农历日期 2016*8*12 2017*闰6*12,2017*闰6*12 ClassMethod ToLuner(gl = {+$h}) { //q "2016*8*12" s Nmonth="" s Nday="" s ^TMP("Toluner")=$g(gl)

if gl=""{ set gldt=$h set gldays=$p(gldt,",",1) set gl=$zd(gldays,4) }else{ set gldays=$zdh(gl,4) } ;获取传过来的年份 set year=$p(gl,"/",3) ;查询数据库,获取这个年份的信息串 set calId="" Set calId = $o(^websys.CalendarUtilI("YearIndex"," "_year,calId)) q:calId="" "" s g=$list(^websys.CalendarUtilD(calId),1,3) Set calInfo = $list(g,2) b ;获取这个信息串的春节 s springFes=$p(calInfo,"^",3) ;如果要查询的日期在春节之前,获取前一年的信息串 if (gldays

公历日期与农历日期的相互转换程序

公历日期与农历日期的相互转换程序 //********************************** // 公历日期与农历日期的相互转换程序 // 公元1800年1月25日~2101年1月28日 // 请在VC++6.0平台运行 //********************************** #include; #include; #include; #include; #include; #include; struct date{ short year,month,day; } d1={ 1800,1,25 },//农历1800正月初一(星期六) d2={ 2101,1,28 };//农历2100腊月廿九(未使用) struct lunarYear //农历年 { char run; //闰月月份(0表示无闰月) char ZL[13]; //农历i月初一对应公历i月ZL[i]日(广义) } Year[2101

//但是ZL[i]的最高位1表示大月0表示小月 -1800]={4};//农历1800年闰四月 #define leap(y) !(y%(y%100?4:400)) //公元闰年宏定义 unsigned char days[]={ 0,31,28,31,30,31,30,31,31,30,31,30,31 }, b[]= //农历1800-2100年大月(30天)小月(29天)闰月数据(hex string) { "adca5aa92bb525bba25bb493b64a5ba9add496ea8a6 ed14eea4a6da5b6" "545baa4bba45bba82b75a5b654abaa55d526eda4aed 495da526daa5655" "abb295ba5257aa4b75a95655abaa56ea4a5da92ed96 5d594adaa56692b" "75a5ba64977493b6ca5a69add496da925dd24dda495 da9add45a6a4b75"

阴历阳历转换算法2

一.简单的历法知识 干支的推算和历法知识是密切相关的,因此大家首先应该对历法有所了解,若已具备相关知识,可跳过此部分。历法是以太阳、月亮、地球三者在运行时间上的关系,制定时间顺序的法则。现行的历法大致分为三类太阳历,太阴历,阴阳历, 1.“太阳历”就是我们所说的“阳历”,是以“回归年” (地球绕太阳运行一周的时间)为侧重点制定历法,首先规定一个“回归年”为一年,为365天,然后规定每年有12个月,1,3,5,7,8,10,12月为大月31天,其余月为30天,由于“回归年”的准确时间是365天5小时48分46秒,四年则与实际回归年差一天,因此每四年设一个“润年”366天。 2.“太阴历”并非我们所说的农历,他是以“朔望月”(月亮绕地球一周的时间)为侧重点,首先规定一个“朔望月”的时间为一个月,然后规定12个月为一年,一个“朔望月”大约为日,因此设大月为30天,小月29天,单月是大月,双月是小月。12个太阴历的月是354天,比回归年差不多短了11天。3年就短一个多月。所以使用这种历时,新年不一定在冬天过,它可以在春天过,也可以在夏天或秋天过。它的惟一好处就是阴历上的每一个日期都可以知道月亮的形状。当今世界上除了几个伊斯兰教国家因为宗教上的原因仍然使用外,其他国家一般已经废弃不用了。 3.“阴阳历”才是我们常说的农历,之所以叫“阴阳历”是因为他兼顾了“回归年”和“朔望月”两个时间特点,他同样是首先规定一个“朔望月”的时间为一个月,大月为30天,小月29天,但农历的大小月由推算决定,以“朔”(月亮不出现的日子)为每个月的初一,并使用“闰月”的办法解决太阴历的不足。为保证每月的头一天(初一)必须是朔日,就使得大小月的安排不固定,而需要通过严格的观测和计算来确定。 设置“润月”的目的是为了使m个回归年的天数与n个朔望月的天数相等,即 m×=n× (1)

相关主题