C语言求两个日期之间间隔的天数

本文介绍了一种使用面向过程的编程方法,模拟小学生翻日历来计算日期间隔的C++代码。虽然效率不高,但易于移植和处理复杂情况,如闰年判断。作者探讨了不采用累加全年天数的优缺点。
摘要由CSDN通过智能技术生成

求解方法有很多,这里用小学生翻日历的笨方法。大致思路如下:定义三个变量year、month、day,用来记录日期,再定义一个变量days,用来计算天数。现在有一本日历放在面前,假设当前日期是2005年3月5日,开始翻日历,翻一页,变量day就加1,日期变成2005年3月6日,继续翻……,翻到了2005年3月31日,此时变量month是3,day是31,继续翻页,变成了3月32日,这时候,我们发现32大于3月份的天数(31),于是,将month加1,并且day置为1。特殊情况,如果是2005年12月31日,如果翻一页日历,就会变成2005年12月32日,先变为2005年13月1日(month加1,并且day置为1),然后变为2006年1月1日(year加1,并且month置为1)。

为什么不整年整年的366或者365天累加呢?那样程序运行效率明显高很多。原因有三:

(1)上面这种原始的写法的好处是很容易把它改成火星上的程序,只需要修改三处:MONTH的值、daysOfMonth的值、IsLeapYear函数体,程序其它逻辑不需要做任何修改。

(2)以上这种很笨的写法,循环体执行一次的时间是纳秒(10的负9次方秒)级别的,即使一百万年的间隔,循环几亿次(10的8次方),整个程序运行时间也不需要1秒钟。

(3)这种一页一页翻日历的思路,不但可以求两天的时间间隔,还可以求从某一天开始往前或者往后经过若干天的日期。前者(求两天的时间间隔)用while循环,后者(从某一天开始往前或者往后经过若干天的日期)用for循环,循环体里的逻辑基本完全一致。

进一步的,这种面向过程的写法可以改成面向对象的,如果利用C++的运算符重载,重载减号运算符,求某两天的间隔天数的形式将非常简单,像下面这样:Date(2023, 9, 29) - Date(2005, 3, 5)。

面向过程的代码如下:

#include <iostream>
using namespace std;

#define MONTH 12

int daysOfMonth[2][MONTH + 1] = { {-1,31,28,31,30,31,30,31,31,30,31,30,31},			//每行多定义一个元素,第一个元素不用
								  {-1,31,29,31,30,31,30,31,31,30,31,30,31} };	

struct Date
{
	int year, month, day;
};

int DateDiff(Date beginDate, Date endDate);
int IsLeapYear(int year);

int main()
{
	Date date1 = { 2005,3,5 };
	Date date2 = { 2023,9,29 };

	cout << "间隔" << DateDiff(date1, date2) << "天" << endl;

	return 0;
}

int DateDiff(Date beginDate, Date endDate)
{
	int year = beginDate.year;
	int month = beginDate.month;
	int day = beginDate.day;
	int days = 0;

	while (!(year == endDate.year && month == endDate.month && day == endDate.day)) 
	{
		day++;

		if (day > daysOfMonth[IsLeapYear(year)][month])	
		{
			day = 1;
			month++;

			if (month > MONTH)	
			{
				month = 1;
				year++;
			}
		}

		days++;
	}

	return days;
}

int IsLeapYear(int year)
{
	if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
		return 1;
	else
		return 0;
}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值