#include <stdio.h>
#include <assert.h>
//日期用结构体表示
typedef struct date{
int year;
int month;
int day;
}Date;
// 闰年:1月到12月每个月的天数 31,29,31,30,31,30,31,31,30,31,30,31
//非闰年:1月到12月每个月的天数 31,28,31,30,31,30,31,31,30,31,30,31
//daysMonth存的是非闰年当前月之前的总天数
int daysMonth[13] = { 0, 0 , 31, 59, 90, 120, 151,
181, 212, 243, 273, 304, 334};
//判断是否是闰年,闰年返回1
int isLeap(const int year)
{
return ( (year % 4 == 0) && (year % 100 != 0) ||
(year % 400 == 0) );
}
//当前日期是一年当中的第几天
int days(const Date * currDate)
{
int sum = daysMonth[currDate->month] + currDate->day;
if ( isLeap(currDate->year) && (currDate->month >= 3) ){
sum++;
}
return sum;
}
//交换两个日期
void swapDate(Date *date1, Date *date2)
{
int tmp;
tmp = date1->year;
date1->year = date2->year;
date2->year = tmp;
tmp = date1->month;
date1->month = date2->month;
date2->month = tmp;
tmp = date1->day;
date1->day = date2->day;
date2->day = tmp;
}
//两个日期间相差的天数,解决[给定某个日子,返回它在一周中属于第几天]
int getIntervalTime(Date *date1, Date *date2)
{
int days1, days2, sumDays;
int i;
int years;
//保证后面的比前面的大
if(date1->year > date2->year){
swapDate(date1, date2);
}
years = date2->year - date1->year;
//当前日期是一年当中的第几天
days1 = days(date1);
days2 = days(date2);
sumDays = days2 - days1;
//两者相差一年
if( years == 1){
sumDays += 365;
}else if(years > 1){//两个日子的年份之间经过几个闰年
for(i = date1->year; i < date2->year; i++){
sumDays += 365;
if(isLeap(i)){
sumDays++;
}
}
}
return sumDays;
}
//这一天是星期几,解决[给定某个日子,返回它在一周中属于第几天]
int whichDay(Date *date)
{
Date orgDate;
int sum;
//1980年1月7日是星期一
orgDate.year = 1980;
orgDate.month = 1;
orgDate.day = 7;
sum = getIntervalTime(date, &orgDate);
sum = (sum % 7 + 1);
return sum;
}
//打印该月的日历,解决[给定某个某年某月,打印这一月的日历]
void printCalenda(Date *date)
{
int today;
int i;
int days;
int cnt;
int m[] = {31,28,31,30,31,30,31,31,30,31,30,31};
days = m[date->month - 1];
if(isLeap(date->year) && date->month >= 2){
days++;
}
assert(date->day == 1);
cnt = today = whichDay(date);
//开始打印
printf(" 日 一 二 三 四 五 六\n");
for(i = 0; i < today; i++){ //这个月的第一天是星期几,这天之前打印空格
printf(" ");//三个空格,因为一个汉字占两个字符的宽度
}
for(i = 1; i < days; i++){
printf(" %2d", i);//从这个月的第一天开始打印
cnt++; //从星期日为这个星期的第一天所以先++
if(cnt %7 == 0){
printf("\n");
}
}
printf("\n");
}
int main()
{
Date date1, date2;
int year, month, day;
#if 0
printf("请输入第一个日期,格式是年 月 日(2004 8 30):");
scanf("%d %d %d", &year, &month, &day);
date1.year = year;
date1.month = month;
date1.day = day;
printf("\n请输入第二个日期,格式是年 月 日(2004 8 30):");
scanf("%d %d %d", &year, &month, &day);
date2.year = year;
date2.month = month;
date2.day = day;
printf("两个日期之间相差%d天\n", getIntervalTime(&date1, &date2));
#else
date2.year = 2010;
date2.month = 1;
date2.day = 1;
//whichDay(&date2);
printCalenda(&date2);
#endif
return 0;
}
|