日历转换(200分)

  • 主题发起人 主题发起人 pjzdz
  • 开始时间 开始时间
P

pjzdz

Unregistered / Unconfirmed
GUEST, unregistred user!
农历与公历转换的算法如何?
Mail一份说明或源码吧!
E_mail: zjpjzdz@sina.com
 
我一直也在找这种算法,曾听说有人实现过没有设定范围的那种,不过我没看到算法,
(当时是在济南万千新闻组中听说的,那位兄弟说不难,可以参考某图书...),到现在
为止, 我也没找着,只有一些有年份限制的算法,我找找看,先申明,别说我侵权,
学习学习嘛。

  西历农历转换程式
  程序中用到的数据结构说明,根据这个说明你可以加一些外观,做成一个阴阳历转换程序。所提供的程序已在Borland C++中调试通过:
struct convdate
{
  int source;//==0则输入日期为西历,!=0则输入为农历
  int solaryear;//输出或输入之西历年份
  int solarmonth;//西历月
  int solardate;//西历日
  int lunaryear;//输出或输入之农历年份
  int lunarmonth;//农历月
  int lunardate;//农历日
  int weekday;//该日为星期几(0==星期日,1==星期一,...)
  int kan;//该日天干(0==甲,1==乙,...,9==癸
  int chih;//该日地支(0==子,1==丑,..,11==亥)
};
struct taglunarcal
{
  int basedays;
/* 到西历 1 月 1 日到农历正月初一的累积日数 */
  int intercalation;
/* 闰月月份. 0==此年没有闰月 */
  int baseweekday;
/* 此年西历 1 月 1 日为星期几再减 1 */
  int basekanchih;
/* 此年西历 1 月 1 日之干支序号减 1 */
  int monthdays[13];
/* 此农历年每月之大小, 0==小月(29日), 1==大月(30日)*/
};
  呼叫时须设定souce的值,若为0则为西历转农历,否则为农历转西历。然后视输入为西历或西历的年月日。转换后的年月日会填入结构中(农历或西历)。以及该日为星期几,天干地支。若函式的返回值为0表示没有错误,1为输入之年份错误,2为输入之月份错误,3为输入之日错误。
  输入之西历须在1937-2031间
  输入之农历须在1936-2030间
  若须扩充,则增加lunarcal[]

BC++ 源程序
#define firstyear 1936 /* the first year in lunarcal[] */
#include "iostream.h"
#include "conio.h"
struct convdate
{
int source;
int solaryear;
int solarmonth;
int solardate;
int lunaryear;
int lunarmonth;
int lunardate;
int weekday;
int kan;
int chih;
};
struct taglunarcal
{
int basedays;
int intercalation;
int baseweekday;
int basekanchih;
int monthdays[13];
};
struct taglunarcal lunarcal[] = {
{ 23, 3, 2, 17, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0 }, /* 1936 */
{ 41, 0, 4, 23, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1 },
{ 30, 7, 5, 28, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 },
{ 49, 0, 6, 33, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
{ 38, 0, 0, 38, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, /* 1940 */
{ 26, 6, 2, 44, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
{ 45, 0, 3, 49, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },
{ 35, 0, 4, 54, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
{ 24, 4, 5, 59, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 }, /* 1944 */
{ 43, 0, 0, 5, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1 },
{ 32, 0, 1, 10, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 },
{ 21, 2, 2, 15, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
{ 40, 0, 3, 20, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 }, /* 1948 */
{ 28, 7, 5, 26, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
{ 47, 0, 6, 31, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1 },
{ 36, 0, 0, 36, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },
{ 26, 5, 1, 41, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 }, /* 1952 */
{ 44, 0, 3, 47, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1 },
{ 33, 0, 4, 52, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 },
{ 23, 3, 5, 57, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 },
{ 42, 0, 6, 2, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 }, /* 1956 */
{ 30, 8, 1, 8, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
{ 48, 0, 2, 13, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
{ 38, 0, 3, 18, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 },
{ 27, 6, 4, 23, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 }, /* 1960 */
{ 45, 0, 6, 29, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0 },
{ 35, 0, 0, 34, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 24, 4, 1, 39, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 },
{ 43, 0, 2, 44, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 }, /* 1964 */
{ 32, 0, 4, 50, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 },
{ 20, 3, 5, 55, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 },
{ 39, 0, 6, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0 },
{ 29, 7, 0, 5, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, /* 1968 */
{ 47, 0, 2, 11, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
{ 36, 0, 3, 16, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0 },
{ 26, 5, 4, 21, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1 },
{ 45, 0, 5, 26, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 }, /* 1972 */
{ 33, 0, 0, 32, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1 },
{ 22, 4, 1, 37, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 },
{ 41, 0, 2, 42, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1 },
{ 30, 8, 3, 47, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 }, /* 1976 */
{ 48, 0, 5, 53, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1 },
{ 37, 0, 6, 58, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
{ 27, 6, 0, 3, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0 },
{ 46, 0, 1, 8, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0 }, /* 1980 */
{ 35, 0, 3, 14, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1 },
{ 24, 4, 4, 19, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 },
{ 43, 0, 5, 24, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 },
{ 32, 10, 6, 29, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1 }, /* 1984 */
{ 50, 0, 1, 35, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
{ 39, 0, 2, 40, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1 },
{ 28, 6, 3, 45, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0 },
{ 47, 0, 4, 50, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, /* 1988 */
{ 36, 0, 6, 56, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0 },
{ 26, 5, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1 },
{ 45, 0, 1, 6, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0 },
{ 34, 0, 2, 11, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0 }, /* 1992 */
{ 22, 3, 4, 17, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
{ 40, 0, 5, 22, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
{ 30, 8, 6, 27, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1 },
{ 49, 0, 0, 32, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1 }, /* 1996 */
{ 37, 0, 2, 38, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 27, 5, 3, 43, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 46, 0, 4, 48, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1 },
{ 35, 0, 5, 53, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 }, /* 2000 */
{ 23, 4, 0, 59, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
{ 42, 0, 1, 4, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
{ 31, 0, 2, 9, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
{ 21, 2, 3, 14, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, /* 2004 */
{ 39, 0, 5, 20, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
{ 28, 7, 6, 25, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 },
{ 48, 0, 0, 30, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1 },
{ 37, 0, 1, 35, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 }, /* 2008 */
{ 25, 5, 3, 41, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
{ 44, 0, 4, 46, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },
{ 33, 0, 5, 51, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
{ 22, 4, 6, 56, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }, /* 2012 */
{ 40, 0, 1, 2, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },
{ 30, 9, 2, 7, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 },
{ 49, 0, 3, 12, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1 },
{ 38, 0, 4, 17, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 }, /* 2016 */
{ 27, 6, 6, 23, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 },
{ 46, 0, 0, 28, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0 },
{ 35, 0, 1, 33, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 },
{ 24, 4, 2, 38, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, /* 2020 */
{ 42, 0, 4, 44, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 },
{ 31, 0, 5, 49, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 },
{ 21, 2, 6, 54, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 },
{ 40, 0, 0, 59, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, /* 2024 */
{ 28, 6, 2, 5, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 },
{ 47, 0, 3, 10, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1 },
{ 36, 0, 4, 15, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 },
{ 25, 5, 5, 20, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 }, /* 2028 */
{ 43, 0, 0, 26, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 },
{ 32, 0, 1, 31, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0 },
{ 22, 3, 2, 36, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0 } };
#define lastyear (firstyear+sizeof(lunarcal)/sizeof(struct taglunarcal)-1)
/* 西历年每月之日数 */
int solarcal[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
/* 西历年每月之累积日数, 平年与闰年 */
int solardays[2][14] = {
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 396 },
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366, 397 } };
/* 求此西历年是否为闰年, 返回 0 为平年, 1 为闰年 */
int getleap( int year )
{
if ( year % 400 == 0 )
return 1;
else
if ( year % 100 == 0 )
return 0;
else
if ( year % 4 == 0 )
return 1;
else
return 0;
}
/* 西历农历转换 */
int calconv( struct convdate *cd )
{
int leap, d, sm, y, im, l1, l2, acc, i, lm, kc;
if ( cd->source == 0 ) /* solar */
{
if ( cd->solaryear <= firstyear || cd->solaryear > lastyear )
return 1;
sm = cd->solarmonth - 1;
if ( sm < 0 || sm > 11 )
return 2;
leap = getleap( cd->solaryear );
if ( sm == 1 )
d = leap + 28;
else
d = solarcal[sm];
if ( cd->solardate < 1 || cd->solardate > d )
return 3;
y = cd->solaryear - firstyear;
acc = solardays[leap][sm] + cd->solardate;
cd->weekday = ( acc + lunarcal[y].baseweekday ) % 7;
kc = acc + lunarcal[y].basekanchih;
cd->kan = kc % 10;
cd->chih = kc % 12;
if ( acc <= lunarcal[y].basedays )
{
y--;
cd->lunaryear = cd->solaryear - 1;
leap = getleap( cd->lunaryear );
sm += 12;
acc = solardays[leap][sm] + cd->solardate;
}
else
cd->lunaryear = cd->solaryear;
l1 = lunarcal[y].basedays;
for ( i=0;
i<13;
i++ )
{
l2 = l1 + lunarcal[y].monthdays + 29;
if ( acc <= l2 )
break;
l1 = l2;
}
cd->lunarmonth = i + 1;
cd->lunardate = acc - l1;
im = lunarcal[y].intercalation;
if ( im != 0 &&
cd->lunarmonth > im )
{
cd->lunarmonth--;
if ( cd->lunarmonth == im )
cd->lunarmonth = -im;
}
if ( cd->lunarmonth > 12 )
cd->lunarmonth -= 12;
}
else
/* lunar */
{
if ( cd->lunaryear < firstyear || cd->lunaryear >= lastyear )
return 1;
y = cd->lunaryear - firstyear;
im = lunarcal[y].intercalation;
lm = cd->lunarmonth;
if ( lm < 0 )
{
if ( lm != -im )
return 2;
}
else
if ( lm < 1 || lm > 12 )
return 2;
if ( im != 0 )
{
if ( lm > im )
lm++;
else
if ( lm == -im )
lm = im + 1;
}
lm--;
if ( cd->lunardate > lunarcal[y].monthdays[lm] + 29 )
return 3;
acc = lunarcal[y].basedays;
for ( i=0;
i<13;i++){
acc += lunarcal[y].monthdays + 29;
acc += cd->lunardate;
leap = getleap( cd->lunaryear );
}
for ( i=13;
i>=0;
i-- )
if ( acc > solardays[leap] )
break;
cd->solardate = acc - solardays[leap];
if ( i <= 11 )
{
cd->solaryear = cd->lunaryear;
cd->solarmonth = i + 1;
}
else
{
cd->solaryear = cd->lunaryear + 1;
cd->solarmonth = i - 11;
}
leap = getleap( cd->solaryear );
y = cd->solaryear - firstyear;
acc = solardays[leap][cd->solarmonth-1] + cd->solardate;
cd->weekday = ( acc + lunarcal[y].baseweekday ) % 7;
kc = acc + lunarcal[y].basekanchih;
cd->kan = kc % 10;
cd->chih = kc % 12;
}
return 0;
}
void main(){
struct convdate *p;
p->source=0;
p->solaryear=2001;
p->solarmonth=4;
p->solardate=26;
calconv(p);
cout<<p->lunaryear<<','<<p->lunarmonth<<','<<p->lunardate<<endl;
getch();
}
我从这里找的
http://goodeye.ecjtu.jx.cn/~wybs67/program/yinyang1.htm
Delphi源程序(暴力法)
http://bluegem.dhs.org/cgi-bin/bbscon?board=Algorithm&file=M.962853445.A&num=8
 
这个没有什么算法的,只有用查表的办法才能解决。你可以找找以前的帖子。
 
谢谢两位。
 
后退
顶部