C语言编写一个带农历的万年历

老师布置了一个作业.叫我们编写一个万年历.结果交作业他说要带有农历的.郁闷死了.都两天了.一直不知道怎么写农历.有高手帮帮忙么.写得好的还能追加分
#include <stdio.h>

int JgYr(int yr)
{
if (yr%4==0&&yr%100!=0||yr%100==0&&yr%400==0)
return 1;
else
return 0;
}

int CalWkd(int yr,int mth)
{
int ds=0,i,rst,wkd;
int mthd[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
if (JgYr(yr))
mthd[2]=29;
for (i=1;i<mth;i++)
ds+=mthd[i];
ds+=1;
rst=yr-1+(int)((yr-1)/4)-(int)((yr-1)/100)+(int)((yr-1)/400)+ds;
wkd=rst%7;
return wkd;
}

showcld(int wkd,int mtd)
{
int dt=1,i,j=0;
printf("Sun\tMon\tTue\tWed\tThu\tFri\tSat\n");
for (i=0;i<wkd;i++)
{
printf("\t");
j++;
}
while (j!=7)
{
printf("%d",dt);
if (j<6)
printf("\t");
else
printf("\n");
dt++;
j++;
}
while (1)
{
for (j=0;j<7;j++)
{
printf("%d",dt);
if (j!=6)
printf("\t");
else
printf("\n");
if (dt!=mtd)
dt++;
else
return 0;
}
}
}

int main()
{
int yr,mth,mtd,wkd,mthd[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
printf("Input the Year and Month(Year-Month):");
scanf("%d-%d",&yr,&mth);
if (yr<0||mth<1||mth>12)
return 0;
if (JgYr(yr))
mthd[2]=29;
mtd=mthd[mth];
wkd=CalWkd(yr,mth);
showcld(wkd,mtd);
return 0;
}
这个是没有农历的..求高手帮帮忙写个带农历的

农历算法太复杂了,我查了一下,有个人写出来了,但是我怎么看也看不懂,不知道你能不能看懂! (只是探讨一下,我也想写个农历算法)
首先,我们要确定一个时刻,作为一天的起点(包括这个时刻)。然后我们以月亮通过朔望交界点的那一
天作为每个月的第一天,以太阳通过雨水点的那个月作为正月,依次的,以太阳通过各中气点的那个月作为
二月、三月等等。 经过长期的观察之后,我们就会发现每个月不是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天。
因为每月的天数不固定,所以闰月的出现规律也不好讨论,连续十二个月的天数也不固定,
所以闰年的出现规律也不好讨论。不过可以肯定是,每年的第一个月肯定不是闰月,因为我们
是以包含中气雨水的月份作为正月,也就是每年的第一个月的。所以,闰月必定出现在某个有
名字的月份后面,出现在哪个后面就叫闰哪月。
温馨提示:答案为网友推荐,仅供参考
第1个回答  推荐于2016-01-03
没有农历的如下:

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>

int leap(int year )
{
if ((year %4 == 0) && (year % 100 != 0)
|| (year % 400 == 0))
{
return 1;
}
return 0;
}

void show(int year,int month)
{
const char month_str[][4]={"","Jan","Feb","Mar","Apl",
"May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
const int month_day[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int i,j,wdays,mdays,days;

for(i=1,days=0;i<year;i++)
{
if(leap(i))
{
days += 366;
}
else
{
days += 365;
}
}
for(i=1;i<month;i++)
{
if(i==2 && leap(year))
{
days+=29;
}
else
{
days+=month_day[i];
}
}

printf(" %s (%d)\n",month_str[month],year);
printf(" Mon Tue Wed Thu Fri Sat Sun\n");
wdays = days % 7;
for( j = 0; j < wdays; j++)
{
printf("%4c",' ');
}
if(month == 2 && leap(year))
{
mdays=29;
}
else
{
mdays= month_day[month];
}
for(i=1;i<=mdays;i++)
{
if( i > 1 && days % 7 == 0 )
{
printf("\n");
}
printf("%4d",i);
days=days+1;
}
printf("\n---------------------------\n");
}

void main()
{
time_t rawtime;
struct tm *info;
int year,month;
char ch;

time ( &rawtime );
info = localtime ( &rawtime );
year =info->tm_year + 1900;
month =info->tm_mon + 1;
while(1)
{
show(year,month);
printf("Left....Prev Month\n");
printf("Right...Next Month\n");
printf("Up......Prev Year\n");
printf("Down....Next Year\n");
printf("Esc.....Exit\n");
ch=getch();
switch(ch)
{
case 27://Ecs
exit(0);
case -32://Navigator
ch=getch();
if(ch==77)
{//Right
year+=(month==12)?1:0;
month=month%12+1;
}
else if(ch==75)
{//Left
year-=(month==1)?1:0;
month=(month-2+12)%12+1;
}
else if(ch==72)
{//Up
year--;
}
else if(ch==80)
{//Down
year++;
}
system("cls");
}
}
}

公历转农历的方法很多:
http://www.baidu.com/s?wd=%D1%F4%C0%FA+%D7%AA+%C5%A9%C0%FA+c本回答被提问者采纳
第2个回答  2008-09-17
我也需要这个东东,做个标记
相似回答