日期计算器

#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下运行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值