#include <stdio.h>
#include <string.h>
typedef struct _date
{
int year;
int month;
int day;
}date;
static int month_day_dic[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
//判断是否闰年
int is_leap_year(int year)
{
return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
}
//交换两个日期
void date_swap(date * d1, date * d2)
{
date t;
t = *d1;
*d1 = *d2;
*d2 = t;
}
//比较两个日期
int date_compare(date d1, date d2)
{
if(d1.year > d2.year)
return 1;
else if(d1.year == d2.year){
if(d1.month > d2.month){
return 1;
}
else if(d1.month == d2.month){
if(d1.day > d2.day){
return 1;
}
else if(d1.day == d2.day){
return 0;
}
else{
return -1;
}
}
else{
return -1;
}
}
else
return -1;
}
//打印日期
void show_date(date d)
{
printf("%d %d %d\n",d.year, d.month, d.day);
}
//设置日期
void setdate(date *in, int year, int month, int day)
{
in->year = year;
in->month = month;
in->day = day;
}
//映射
void weekdic(int num, char * weekday)
{
switch(num)
{
case 1:
strcpy(weekday, "一");
break;
case 2:
strcpy(weekday, "二");
break;
case 3:
strcpy(weekday, "三");
break;
case 4:
strcpy(weekday, "四");
break;
case 5:
strcpy(weekday, "五");
break;
case 6:
strcpy(weekday, "六");
break;
case 7:
strcpy(weekday, "日");
break;
default:
printf("异常\n");
}
int len = strlen(weekday);
weekday[len] = '\0';
}
/********************************************
* 函数名:date2days
* 输入:d - 日期
* 输出:无
* 返回值:当前日期与那一年的1月1日的间隔
********************************************/
int date2days(date d)
{
if(is_leap_year(d.year))
month_day_dic[2] = 29;
else
month_day_dic[2] = 28;
int ret = 0;
int i = 1;
for(; i<d.month; i++)
ret += month_day_dic[i];
ret = ret + d.day - 1;
return ret;
}
/********************************************
* 函数名:date2weekday
* 输入:in - 日期
* 返回值:星期几
* 功能:计算输入的日期是星期几
********************************************/
int date2weekday(date in)
{
date origin;
setdate(&origin, 1901, 1, 1);
return interval_between_dates(origin, in)%7 + 2;
}
/********************************************
* 函数名:date2weeks
* 输入:in - 日期
* 返回值:该年的第几周
* 功能:计算日期在第几周
********************************************/
int date2weeks(date in)
{
int weekday;
int the_day;
int the_week;
int total_day_first_week;
date origin;
setdate(&origin, in.year, 1, 1);
weekday = date2weekday(origin);
the_day = date2days(in) + 1;
total_day_first_week = 7 - weekday + 1;
if(the_day - total_day_first_week <= 0)
{
the_week = 1;
}
else
{
the_week = (the_day - total_day_first_week - 1)/7 + 2;
}
return the_week;
}
/********************************************
* 函数名:date_after_several_days
* 输入:in - 起始日期,days - 距离的天数
* 输出:out - 距离起始日期若干天后的日期
* 功能:计算几天后的日期
********************************************/
void date_after_several_days(date in, int days, date * out)
{
int i, total_day, end_year, end_month, end_day, days_of_year;
total_day = date2days(in) + days;
end_year = in.year;
end_month = 1;
end_day = 1;
if(is_leap_year(end_year))
days_of_year = 366;
else
days_of_year = 365;
while(total_day >= days_of_year)
{
end_year++;
total_day -= days_of_year;
if(is_leap_year(end_year))
days_of_year = 366;
else
days_of_year = 365;
}
if(is_leap_year(end_year))
month_day_dic[2] = 29;
else
month_day_dic[2] = 28;
for(i = 1; i <= 12 && total_day > 0; i++)
{
if(total_day > month_day_dic[i])
{
end_month++;
total_day -= month_day_dic[i];
}
else
{
end_day += total_day;
break;
}
}
out->year = end_year;
out->month = end_month;
out->day = end_day;
}
/********************************************
* 函数名:interval_between_dates
* 输入:begin - 起始日期,end - 结束日期
* 输出:无
* 功能:计算两个日期之间间隔的天数
* 返回值:间隔的天数
********************************************/
int interval_between_dates(date begin, date end)
{
int ret = 0;
int i;
if(date_compare(begin,end) > 0)
{
date_swap(&begin, &end);
}
for(i = begin.year; i < end.year; i++)
{
if(is_leap_year(i))
ret += 366;
else
ret += 365;
}
ret = ret + date2days(end) - date2days(begin);
return ret;
}
void main()
{
date in, out;
int days = 0;
int choose = 0;
memset(&in, 0, sizeof(in));
memset(&out, 0, sizeof(out));
printf("\n");
printf(" 日期计算器 \n");
printf("+---------------------------+\n");
printf("|序 号| 功 能 |\n");
printf("+---------------------------+\n");
printf("| 1 | 计算日期差 |\n");
printf("+---------------------------+\n");
printf("| 2 | 推算若干天后的日期 |\n");
printf("+---------------------------+\n");
printf("| 3 | 推算日期是星期几 |\n");
printf("+---------------------------+\n");
printf("| 4 | 推算日期在第几周 |\n");
printf("+---------------------------+\n");
printf("| 5 | 推算日期是第几天 |\n");
printf("+---------------------------+\n");
printf("| 0 | 退出 |\n");
printf("+---------------------------+\n");
printf("\n");
printf("提示:日期格式为YYYY MM DD(如:1990 02 06)\n\n");
printf("请选择序号:");
scanf("%d", &choose);
switch(choose)
{
case 0:
break;
case 1:
printf("起始日期:");
scanf("%d%d%d", &in.year, &in.month, &in.day);
printf("结束日期:");
scanf("%d%d%d", &out.year, &out.month, &out.day);
printf("相差%d天\n", interval_between_dates(in, out));
break;
case 2:
printf("起始日期:");
scanf("%d%d%d", &in.year, &in.month, &in.day);
printf("距离天数:");
scanf("%d", &days);
date_after_several_days(in, days, &out);
printf("%d天后是%d年%d月%d日\n",days, out.year, out.month, out.day);
break;
case 3:
printf("输入日期:");
scanf("%d%d%d", &in.year, &in.month, &in.day);
char week[10] = {0};
weekdic(date2weekday(in), week);
printf("%d年%d月%d日是星期%s\n", in.year, in.month, in.day, week);
break;
case 4:
printf("输入日期:");
scanf("%d%d%d", &in.year, &in.month, &in.day);
printf("%d年%d月%d日是%d年的第%d周\n", in.year, in.month, in.day, in.year, date2weeks(in));
break;
case 5:
printf("输入日期:");
scanf("%d%d%d", &in.year, &in.month, &in.day);
printf("%d年%d月%d日是%d年的第%d天\n", in.year, in.month, in.day, in.year, date2days(in)+1);
break;
default:
printf("输入的序号不在正常范围\n");
}
}
Linux下运行结果: