《编程珠玑》习题3.7.3

题目:编写处理一下日期问题的函数:给定两个日期,计算两者之间的天数;给定一个日期,返回值为周几;给定月和年,使用字符数组生成该月的日历。
以下内容转自 http://www.netmediac.com/article/3463.html
「分析」
1. 给定两个日子,计算两个日子之间的天数
解决思路:
①计算该日子是该年当中的第几天;
②闰年的处理;
③两个日子的年份之间经过几个闰年。

2. 给定某个日子,返回它在一周中属于第几天
解决思路:
①给出一个是星期一的具体日子;
②(计算当前日子-指定日子)相差的天数%7 + 1

3. 给定某个某年某月,打印这一月的日历
解决思路:
①某年某月的第一天是星期几;
②打印的格式
#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;
        
}

你可能感兴趣的:(编程,职场,日历,休闲)