第2个回答 2009-03-20
/*
*计算任意年、月的第一天距2007-1-1有多少天,然后利用余运算得出那一天的
*星期数,就可以显示本月月历。主程序直接使用的函数就是显示月历的函数
*void cal(int y,int m)。显示月历的函数只要是调用判断指定年、月第一天
*是星期的函数int mweek(int y,int *m),这个函数关键是调用的关键是计算
*两个日志之间相差天数的函数int days*(int y1, int m1, int y2, int m2)。
*/
#include <stdio.h>
/*函数返回y年m月的天数:28、29、30、31*/
int mdays(int y,int m){
int d=31;
if (m==4||m==6||m==9||m==11) d=30;
else if (m==2) d=(y%4==0 && y%100!=0 || y%400==0)?29:28;
return d;
}
/*函数返回y年的天数:365、366*/
int ydays(int y){
int d=0;
d=(y%4==0 && y%100!=0 || y%400==0)?366:365;
return d;
}
/*返回两个日期之间的天数:y1-m1-1、y2-m2-1*/
int days(int y1, int m1, int y2, int m2){
int x,y=1;
if (y1>y2 || y1==y2 && m1>m2){
y=-1;
x=y1;y1=y2;y2=x;x=m1;m1=m2;m2=x;
}
x=0;
while(y1+1<y2){x+=ydays(y1);y1++;}
while(y1!=y2 || m1!=m2){
x+=mdays(y1,m1);
m1++;
if(m1>12){m1=1;y1++;}
}
return x*y;
}
/*计算y年m月1日是星期几:0~6*/
int mweek(int y,int m){
int d;
d=days(2007,1,y,m)+1;/*2007-1-1 is MON*/
d%=7;
if (d<0)d+=7;
return d;
}
/*显示y年m月的日历*/
void cal(int y,int m){
int i,j;
printf("SUN\tMON\tTUE\tWED\tTHU\tFRI\tSAT\n");
j=mweek(y,m);
for (i=0;i<j;i++)printf("\t");
for (i=1;i<=mdays(y,m);i++){
printf("%d\t",i);
j++;
if (j>6) {printf("\n");j=0;}
}
}
/*主程序*/
main(){
int y,m;
while(1){
printf("\nEnter year to display calendar (0 to exit):");
scanf("%d",&y);
if (y==0) break;
while(1){
printf("\nEnter month in %d to display calendar (1-12, 0 to Exit):",y);
scanf("%d",&m);
if (m>0 && m<13) cal(y,m);
else break;
}
}
}
第4个回答 2009-03-20
大致要注意以下几点:
1.通常编万年历都是以1900年1月1日,星期一为标准。
2.闰年判断方法:
两个条件满足其一,假设年份为n。
则满足 n%4==0 && n%100!=0 或者n%400==0;其实编程的时候这2句是写在一起的 n%4==0 && n%100!=0 || n%400==0(因为&&优先级比||高,所以加不加括号都没问题)
3.月份,无非就是大、小月外加闰2月的判断。这个简单。
4.通过2,3两步可以得到,从1900年1月1日起到输入的月份的1日为止共经过多少天,假设这个天数为x。则“星期n”可以通过 x%7得到(0就是星期一,1就是星期二,依次)。
思路就是上面这些,晚年历基本都这么做的。要是真有什么不一样,也就是基准日期的选择。因为我见过有人用公元0年1月1日,星期天做基准(估计是信上帝的。。。不过据说究竟是星期日还是星期天,他们自己内部都没统一:)题外话,略过即可)