网上万年历算法

x 400年: (大周期) =146097天 = 7 * 20871 + 0天
x 100年: 000年 = 7 * 0 + 0 + 1 - 1 1 = 0 * 2 + 1 ****
100年 = 7 * 5217 + 7 + 1 - 2 2 = 1 * 2
200年 = 7 * 10435 + 7 + 1 - 4 4 = 2 * 2
300年 = 7 * 15653 + 7 + 1 - 6 6 = 3 * 2

{1,2,4,6}



#include
long int f(int year,int month)
{/*f(年,月)=年-1,如月<3;否则,f(年,月)=年*/
if(month<3) return year-1;
else return year;
}

long int g(int month)
{/*g(月)=月+13,如月<3;否则,g(月)=月+1*/
if(month<3) return month+13;
else return month+1;
}

long int n(int year,int month,int day)
{
/*N=1461*f(年、月)/4+153*g(月)/5+日*/
return 1461L*f(year,month)/4+153L*g(month)/5+day;
}

int w(int year,int month,int day)
{
/*w=(N-621049)%7(0<=w<7)*/
return(int)((n(year,month,day)%7-621049L%7+7)%7);
}

int date[12][6][7];
int day_tbl[ ][12]={{31,28,31,30,31,30,31,31,30,31,30,31},
{31,29,31,30,31,30,31,31,30,31,30,31}};
main()
{int sw,leap,i,j,k,wd,day;
int year;/*年*/
char title[]="SUN MON TUE WED THU FRI SAT";
clrscr();
printf("Please input the year whose calendar you want to know: ");/*输入年*/
scanf("%d%*c",&year);/*输入年份值和掠过值后的回车*/
sw=w(year,1,1);
leap=year%4==0&&year%100||year%400==0;/*判闰年*/
for(i=0;i<12;i++)
for(j=0;j<6;j++)
for(k=0;k<7;k++)
date[i][j][k]=0;/*日期表置0*/
for(i=0;i<12;i++)/*一年十二个月*/
for(wd=0,day=1;day<=day_tbl[leap][i];day++)
{/*将第i+1月的日期填入日期表*/
date[i][wd][sw]=day;
sw=++sw%7;/*每星期七天,以0至6计数*/
if(sw==0) wd++;/*日期表每七天一行,星期天开始新的一行*/
}

printf("\n|==================The Calendar of Year %d =====================|\n|",year);
for(i=0;i<6;i++)
{/*先测算第i+1月和第i+7月的最大星期数*/
for(wd=0,k=0;k<7;k++)/*日期表的第六行有日期,则wd!=0*/
wd+=date[i][5][k]+date[i+6][5][k];
wd=wd?6:5;
printf("%2d %s %2d %s |\n|",i+1,title,i+7,title);
for(j=0;j{
printf(" ");/*输出四个空白符*/
/*左栏为第i+1月,右栏为第i+7月*/
for(k=0;k<7;k++)
if(date[i][j][k])
printf("%4d",date[i][j][k]);
else printf(" ");
printf(" ");/*输出十个空白符*/
for(k=0;k<7;k++)
if(date[i+6][j][k])
printf("%4d",date[i+6][j][k]);
else printf(" ");
printf(" |\n|");
}
/*scanf("%*c");/*键入回车输出下一个月的日历*/

}
puts("=================================================================|");
puts("\n Press any key to quit...");
getch();
}




#include
int leap (int year)
{if(year%4==0&&year%100!=0||year%400==0) //判断是否是闰年
return 1;
else return 0;
}
int days_month (int month,int year) //判断大月和小月
{
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&&leap(year)==1) return 29; //判断二月是29天还是29天
else return 28;
}
int firstday(int month,int year)
{int w;
w=(1+2*month+3*(month+1)/5+year+year/4+year/400-year/100)%7+1; //判断每个月开始的第一天是星期几
return w;
}
main()
{int i,j=1,k=1,a,b,month,year;
printf("\n input month and year:\n");
scanf("%d%d",&month,&year); //输入月和年
b=days_month(month,year);
a=firstday (month,year);
printf(" Sun Mon Tue Wed Thu Fri Sat \n"); //输出对应当月的日历
if(a==7)
{for(i=1;i<=b;i++)
{printf("%4d",i);
if(i%7==0)
{printf("\n");
}
}
}
if(a!=7)
{while (j<=4*a)
{printf(" ");
j++;
}
for(i=1;i<=b;i++)
{printf("%4d",i);
if(i==7*k-a)
{printf("\n");
k++;
}

}
}
printf("\n");
}



#include
#include

char* month_str[]={"January","February","March","April","May","June","July","August","September","October","November","December"};
char* week[]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};

int IsLeapYear(int year) /*find out the year is leap year or not*/
{
if((year%4==0&&year%100!=0)||(year%400==0))
return 1;
else
return 0;

}
int month_day(int year,int month)
{
int mon_day[]={31,28,31,30,31,30,31,31,30,31,30,31};
if(IsLeapYear(year)&&month==2)
return 29;
else
return(mon_day[month-1]);

}
int DaySearch(int year,int month,int day) /*search what day this day is*/
{
int c=0;
float s;
int m;
for(m=1;mc=c+month_day(year,m);
c=c+day;
s=year-1+(float)(year-1)/4+(float)(year-1)/100+(float)(year-1)/400-40+c;
return ((int)s%7);
}

int PrintAllYear(int year)/*print the all year*/
{
int temp;
int i,j;
printf("\n\n%d Calander\n",year);
for(i=1;i<=12;i++)
{
printf("\n\n%s(%d)\n",month_str[i-1],i);
printf("0 1 2 3 4 5 6 \n");
printf("S M T W T F S \n\n");
temp=DaySearch(year,i,1);
for(j=1;j<=month_day(year,i)+temp;j++)
{
if(j-temp<=0)
printf(" ");
else if(j-temp<10)
printf("%d ",j-temp);
else
printf("%d ",j-temp);

if(j%7==0)
printf("\n");
}
}
return 0;
}

int main()
{
int option,da;
char ch;
int year,month,day;
printf("Copyright @ 2005 TianQian All rights reserved!:):):)");
printf("\n\nWelcome to use the WanNianLi system!\n");

while(1)
{
printf("\nPlease select the service you need:\n");
printf("\n1 Search what day the day is");
printf("\n2 Search whether the year is leap year or not");
printf("\n3 Print the calander of the whole year");
printf("\n4 Exit\n");
scanf("%d",&option);

switch(option)
{
case 1:
while(1)
{
printf("\nPlease input the year,month and day(XXXX,XX,XX):");
scanf("%d,%d,%d,%c",&year,&month,&day);
da=DaySearch(year,month,day);
printf("\n%d-%d-%d is %s,d

o you want to continue?(Y/N)",year,month,day,week[da]);
fflush(stdin);
scanf("%c",&ch);
if(ch=='N'||ch=='n')
break;
}
break;
case 2:
while(1)
{
printf("\nPlease input the year which needs searched?(XXXX)");
scanf("%d",&year);
if(IsLeapYear(year))
printf("\n%d is Leap year,do you want to continue?(Y/N)",year);
else
printf("\n%d is not Leap year,do you want to continue(Y/N)?",year);
fflush(stdin);
scanf("%c",&ch);
if(ch=='N'||ch=='n')
break;
}
break;
case 3:
while(1)
{
printf("\nPlease input the year which needs printed(XXXX)");
scanf("%d",&year);
PrintAllYear(year);
printf("\nDo you want to continue to print(Y/N)?");
fflush(stdin);
scanf("%c",&ch);
if(ch=='N'||ch=='n')
break;
}
break;
case 4:
fflush(stdin);
printf("Are you sure?(Y/N)");
scanf("%c",&ch);
if(ch=='Y'||ch=='y')
exit(0);
break;
default:
printf("\nError:Sorry,there is no this service now!\n");
break;
}

}

return 0;
}



/***********************************将公历日期转换成农历*************************************/
void Conversion(bit cenbit,uchar year,uchar month,uchar day)
{
unsigned char temp1,temp2,temp3,MonthP;//temp3,temp4分别表示春节距元旦的天数,公历日离元旦的天数
unsigned int temp4,TableAddr;
bit flag2,flag_y;
temp1=year/16; //BCD->hex 先把数据转换为十六进制 高位
temp2=year%16; //低位
year=temp1*10+temp2; //把 年 数据 转换成16进制
temp1=month/16; //月份 高位
temp2=month%16; //月份 低位
month=temp1*10+temp2; //把 月 数据 转换成16进制
temp1=day/16; //日期 高位
temp2=day%16; //日期 低位
day=temp1*10+temp2; //把 日 数据 转换成16进制
if(cenbit==0) //如果是21世纪
{
TableAddr=(year+0x64-1)*0x03;
string_1[0]='2';
string_1[1]='0';
}
else //如果是20世纪
{
TableAddr=(year-1)*0x03;
string_1[0]='1';
string_1[1]='9';
}
temp1=YearCode[TableAddr+2]&0x60; //取当年春节所在的公历月份 年份表中第三字节BIT6-5表示春节的公历月份
temp1=_cror_(temp1,5); //循环右移5位,得到 春节所在的公历月份
temp2=YearCode[TableAddr+2]&0x1f; //取当年春节所在的公历日 年份表中第三字节BIT4-0表示当年春节所在的公历日
if(temp1==0x01) // 计算当年春年离当年元旦的天数,春节只会在公历1月或2月
temp3=temp2-1;

//假如春节在公历1月,则元旦离春节的天数为 temp2-1 天
else
temp3=temp2+0x1f-1; //假如春节在公历2月,则元旦离春节的天数为 temp2+0x1f-1 天
if (month<10)
temp4=DayCode1[month-1]+day-1; //0到8月某日距元旦的天数
else
temp4=DayCode2[month-10]+day-1; //9月开始的某一天距元旦的天数
if ((month>0x02)&&(year%0x04==0)) //如果公历月大于2月并且该年的2月为闰月,天数加1
temp4+=1;
//计算机出公历日距元旦的天数和春节距元旦的天数,则是为了比较公历日是在春节前还是春节后
//如果temp3>temp4 则 公历日在春节之前
if (temp4>=temp3) //公历日在春节后或就是春节当日使用下面代码进行运算
{
temp4-=temp3; //公历日离春节的天数 因为公历日在春节后 所以为temp4-temp3
month=0x01;
MonthP=0x01; //LunarMonth为月份指向,公历日在春节前或就是春节当日LunarMonth指向首月
flag2=GetMoonDay(MonthP,TableAddr); //检查该农历月为大小还是小月,大月返回1,小月返回0
flag_y=0;
if(flag2==0) //GetMoonDay()函数返回的是0
{temp1=0x1d;} //小月29天
else //GetMoonDay()函数返回的是1
{temp1=0x1e;} //大月30天
temp2=YearCode[TableAddr]&0xf0; //年份数据表中第1字节BIT7-4为闰月,为0则这年无闰月,如为1,表示有闰月
temp2=_cror_(temp2,4); //从数据表中取该年的闰月月份,如为0,则该年无闰月 BIT3-0表示阴历1到4月的大小 1为大 0 为小
while(temp4>=temp1)
{
temp4-=temp1;
MonthP+=1;
if(month==temp2)
{
flag_y=~flag_y;
if(flag_y==0) {month+=1;}
}
else
{
month+=1;
}
flag2=GetMoonDay(MonthP,TableAddr);
if(flag2==0)
{
temp1=0x1d;
}
else
{
temp1=0x1e;
}
}
day=temp4+1;
}
else
{ //公历日在春节前使用下面代码进行运算
temp3-=temp4; //公历日离春节的天数 因为公历日在春节前 所以为temp3-temp4
if (year==0x00){year=0x63;cenbit=1;}
else year-=1;
TableAddr-=0x03;
month=0x0c;
temp2=YearCode[TableAddr]&0xf0; //格式第一字节BIT7-4位表示闰月月份,为0,则无闰月,BIT3-0对应阴历第1-4月的大小,
temp2=_cror_(temp2,4);
if (temp2==0)MonthP=0x0c;
else MonthP=0x0d; //
/* MonthP为月份指向,如果当年有闰月,一年

有十三个月,月指向13,无闰月指向12*/
flag_y=0;
flag2=GetMoonDay(MonthP,TableAddr);
if(flag2==0)temp1=0x1d;
else temp1=0x1e;
while(temp3>temp1)
{
temp3-=temp1;
MonthP-=1;
if(flag_y==0)month-=1;
if(month==temp2)flag_y=~flag_y;
flag2=GetMoonDay(MonthP,TableAddr);
if(flag2==0)temp1=0x1d;
else temp1=0x1e;
}
day=temp1-temp3+1;
}
c_moon=cenbit;
temp1=year/10;
temp1=_crol_(temp1,4);
temp2=year%10;
LunarYear=temp1|temp2;

temp1=month/10;
temp1=_crol_(temp1,4);
temp2=month%10;
LunarMonth=temp1|temp2;

temp1=day/10;
temp1=_crol_(temp1,4);
temp2=day%10;
LunarDay=temp1|temp2;
}


/***********************************************************
******************设置时间函数******************
************************************************************/
void SetTime(char count)
{
uchar address,item;
uchar max,mini;

DisplayListChar(0, 4,"《 调整");
if(count==6) {DisplayListChar(4, 4,"秒钟 》");address=0x81; max=59;mini=0;}
if(count==5) {DisplayListChar(4, 4,"分钟 》");address=0x83; max=59;mini=0;}
if(count==4) {DisplayListChar(4, 4,"小时 》");address=0x85; max=23;mini=0;}
if(count==3) {DisplayListChar(4, 4,"星期 》");address=0x8b; max=7;mini=1;}
if(count==2) {DisplayListChar(4, 4,"日期 》");address=0x87; max=31;mini=1;}
if(count==1) {DisplayListChar(4, 4,"月份 》");address=0x89; max=12;mini=1;}
if(count==0) {DisplayListChar(4, 4,"年份 》");address=0x8d; max=99;mini=0;}
item=Read1302(address);//读取DS1302某地址上的数值赋给item
item=(item/16)*10+item%16;
if(PlusKey==0) //PlusKey-加
item++; //数加 1
if(ReduceKey==0) //ReduceKey-减
item--; //数减 1
if(item>max)
item=mini; //查看数值有效范围
if(itemitem=max;
Write1302(0x8e,0x00);
item=(item/10)*16+item%10;
Write1302(address-1,item); //将调整好的item值写入DS1302
DisplayAllData();
}







相关文档
最新文档