Chinaunix首页 | 论坛 | 博客
  • 博客访问: 471914
  • 博文数量: 134
  • 博客积分: 3056
  • 博客等级: 中校
  • 技术积分: 1150
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-14 15:53
文章分类
文章存档

2013年(1)

2010年(133)

我的朋友

分类: C/C++

2010-11-24 19:47:44

「来源《编程珠玑》习题3.7.4。日期问题:给定两个日子,计算这两个日子之间的天数;给定某个日子,返回它在一周中属于第几天;给定某年某月,打印出这一月份的日历

「分析
1. 给定两个日子,计算两个日子之间的天数
解决思路:
①计算该日子是该年当中的第几天;
②闰年的处理;
③两个日子的年份之间经过几个闰年。

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

3. 给定某个某年某月,打印这一月的日历
解决思路:
①某年某月的第一天是星期几;
②打印的格式

「具体实现windows下(vc6.0, C语言)。参考


#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;
    
}


源代码:
文件: days-11-24.rar
大小: 1KB
下载: 下载
阅读(3750) | 评论(1) | 转发(1) |
给主人留下些什么吧!~~

chinaunix网友2010-11-25 11:49:32

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com