
#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 1

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;

}