日期的计算虽不是一个难题,却也算是比较繁琐的,经常会在一些公司的笔试题中出现。日期计算的关键是要把特殊情况考虑周全,如闰年。下面就对一些常见的计算日期的相关函数进行讨论。先从简单的函数谈起,然后再考虑复杂点的函数,后面的函数会调用前面的函数。

 

1、判断输入的年份是否是闰年。

一年是闰年时,该年的2月会是29天,否则是28天。

闰年有两种情况:

1 该年可以被400整除,如2000年、2400年等。

2)该年可以被4整除,但不能被100整除,如2004年、2008年。

从以上两种情况可以得知,2100年、2200年和2300年并不是闰年。

计算闰年的代码如下:

View Code
/******************************************************************************/
/* 函数名称:IsLeapYear */
/* 功能说明:判断输入的年份是否是闰年 */
/* 闰年有2种情况:(1)可以被400整除的正整数 */
/* (2)不能被100整除,但可以被4整除的正整数 */
/* 只对公元后的年份进行处理,否则抛出异常 */
/* 参 数: */
/* iYear -- 输入的年份 */
/* 返 回 值: */
/* ture -- 输入是闰年时 */
/* false -- 输入不是闰年时 */
/******************************************************************************/
bool IsLeapYear(int iYear)
{
/*检查输入的年份是否合法*/
if (iYear < 1)
{
throw -1;
}

/*判断输入的年份是否是闰年*/
if ((0 == (iYear%400))
|| ((0 != (iYear%100)) && (0 == (iYear%4))))
{
return true;
}
else
{
return false;
}
}

 

 

2、得到一年中的天数。

通过判断该年是不是闰年,就能得到该年的天数,闰年一年为366天,其他为365天。

计算一年的天数的代码如下:

View Code
/******************************************************************************/
/* 函数名称:GetDayCntOfYear */
/* 功能说明:得到输入年份的一年中的天数 */
/* 只对公元后的年份进行处理,否则抛出异常 */
/* 参 数: */
/* iYear -- 输入的年份 */
/* 返 回 值: */
/* 366 -- 输入是闰年时 */
/* 365 -- 输入不是闰年时 */
/******************************************************************************/
int GetDayCntOfYear(int iYear)
{
/*检查输入的年份是否合法*/
if (iYear < 1)
{
throw -1;
}

int iDayCnt = 0;
if (IsLeapYear(iYear))
{
iDayCnt
= 366;
}
else
{
iDayCnt
= 365;
}

return iDayCnt;
}

 

3、得到指定日期是该年中的第几天

要得到指定日期中是概念中的第几天,先要得到该年中的每个月的天数。然后根据输入的月份和日子累加得到输入日期对应的天数。

代码如下:

View Code
/******************************************************************************/
/* 函数名称:GetDayIdxOfYear */
/* 功能说明:得到指定日期是该年的第几天,起始值为1 */
/* 只对公元后的正常日期进行处理,否则抛出异常 */
/* 参 数: */
/* iYear -- 输入的年份 */
/* iMonth -- 输入的月份 */
/* iDay -- 输入的日子 */
/* 返 回 值: */
/* 输入日期在改天中的第几天 */
/******************************************************************************/
int GetDayIdxOfYear(int iYear, int iMonth, int iDay)
{
/*检查输入的年份是否合法*/
if (iYear < 1)
{
throw -1;
}

/*检查输入的月份是否合法*/
if ((iMonth < 1) || (iMonth > 12))
{
throw -1;
}

int iDaysOfYear = 0;

/*得到该年的每个月的天数*/
int iarrDayCntOfMonth[13] = {0, 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
if (IsLeapYear(iYear))
{
iarrDayCntOfMonth[
2] = 29;
}

/*判断输入的日子是否合法*/
if ((iDay < 1) || (iDay > iarrDayCntOfMonth[iMonth]))
{
throw -1;
}

/*累加得到输入日期是在该年的第几天*/
for (int iMonthIdx = 1; iMonthIdx < iMonth; iMonthIdx++)
{
iDaysOfYear
+= iarrDayCntOfMonth[iMonthIdx];
}
iDaysOfYear
+= iDay;

return iDaysOfYear;
}

 

 

4、计算两输入年之间的天数

从起始年的11日开始算起,到终止年的1231日为止。

先计算两年之年的年数,然后以365天计算天数;

再计算两年之间的闰年数,然后补出闰年多出的天数。

代码如下:

View Code
/******************************************************************************/
/* 函数名称:GetDayDif */
/* 功能说明:得到两个指定年之间的天数 */
/* 从EarlyYear年1月1日算起,到iLaterYear年12月31日止 */
/* 终止年必须大于起始年 */
/* 参 数: */
/* iEarlyYear -- 起始年 */
/* iLateYear -- 终止年 */
/* 返 回 值: */
/* 两个输入年之间的天数 */
/******************************************************************************/
int GetDayDif(int iEarlyYear, int iLaterYear)
{
if (iEarlyYear > iLaterYear)
{
throw -1;
}

/*以365年计算,两个输入年之间的天数*/
int iDayDif = (iLaterYear-iEarlyYear+1) * 365;

/*计算两个输入年之间的的闰年次数*/
int iEarlyLeapCnt = (iEarlyYear/4) - (iEarlyYear/100) + (iEarlyYear/400);
int iLaterLeapCnt = (iLaterYear/4) - (iLaterYear/100) + (iLaterYear/400);
int iLeapDif = iLaterLeapCnt - iEarlyLeapCnt;

/*补足闰年的天数*/
iDayDif
+= iLeapDif;

return iDayDif;
}

 

 

5、已知某个日期对应的星期,输入另一个日期,计算其对应的星期。

首先先计算出两个日期之间相隔的天数。

计算两个日期计算之间相隔的天数的方法是,先计算两年之间的天数,然后减去多加的天数,包括起始日期在起始年中的天数,以及终止日期在终止年中还剩的天数。

代码如下:

View Code
class CDate
{
public:
int iYear;
int iMonth;
int iDay;
};

/******************************************************************************/
/* 函数名称:GetDayOfWeek */
/* 功能说明:已知某天的日期,以及该天是星期几,计算出另一个输入日期是星期几 */
/* 其中,0表示星期日,1-6分别表示星期一到星期六 */
/* 参 数: */
/* dateKnown -- 已知的日期和星期 */
/* dateUnknown -- 已知日期,但星期未知 */
/* 返 回 值: */
/* dateUnKnown的日期对应的星期 */
/******************************************************************************/
int GetDayOfWeek(const CDate& dateKnown, int iKnownDayOfWeek,
const CDate& dateUnknown)
{
/*判断输入的年份是否合法*/
if (dateKnown.iYear < 1)
{
throw -1;
}

/*判断输入的月份是否合法*/
if ((dateKnown.iMonth < 1) || (dateKnown.iMonth > 12)
|| (dateUnknown.iMonth < 1) || (dateUnknown.iMonth > 12))
{
throw -1;
}

int iarrDayCntOfMonth[13] = {0, 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};

/*判断已知星期的日期是否合法*/
if (IsLeapYear(dateKnown.iYear))
{
iarrDayCntOfMonth[
2] = 29;
}
else
{
iarrDayCntOfMonth[
2] = 28;
}
if ((dateKnown.iDay < 1)
|| (dateKnown.iDay > iarrDayCntOfMonth[dateKnown.iMonth]))
{
throw -1;
}

/*判断未知星期的日期是否合法*/
if (IsLeapYear(dateUnknown.iYear))
{
iarrDayCntOfMonth[
2] = 29;
}
else
{
iarrDayCntOfMonth[
2] = 28;
}
if ((dateUnknown.iDay < 1)
|| (dateUnknown.iDay > iarrDayCntOfMonth[dateUnknown.iMonth]))
{
throw -1;
}

/*判断已知的星期是否合法*/
if ((iKnownDayOfWeek < 0) || (iKnownDayOfWeek > 6))
{
throw -1;
}

/*用于保存两个日期之间相差的天数*/
int iDayDif = 0;

/*根据年份的前后,设定年份小的为起始年,年份大的为终止年*/
/*先得到起始年和终止年之间的天数*/
/*然后减去起始日期在该年中的天数*/
/*再减去终止日期在该年中剩余的天数*/
if (dateUnknown.iYear > dateKnown.iYear)
{
iDayDif
= GetDayDif(dateKnown.iYear, dateUnknown.iYear);
iDayDif
-= GetDayIdxOfYear(dateKnown.iYear, dateKnown.iMonth, dateKnown.iDay);
iDayDif
-= GetDayCntOfYear(dateUnknown.iYear)
- GetDayIdxOfYear(dateUnknown.iYear, dateUnknown.iMonth, dateUnknown.iDay);
}
else
{
iDayDif
= GetDayDif(dateUnknown.iYear, dateKnown.iYear);
iDayDif
-= GetDayIdxOfYear(dateUnknown.iYear, dateUnknown.iMonth, dateUnknown.iDay);
iDayDif
-= GetDayCntOfYear(dateKnown.iYear)
- GetDayIdxOfYear(dateKnown.iYear, dateKnown.iMonth, dateKnown.iDay);

iDayDif
*= -1;
}

/*得到输入的日期的星期*/
int iUnknownDayOfWeek = (iKnownDayOfWeek + iDayDif) % 7;
if (iUnknownDayOfWeek < 0)
{
iUnknownDayOfWeek
+= 7;
}

return iUnknownDayOfWeek;
}

 

 

6、测试的Main函数如下:

View Code
void main()
{

/*已知2011年7月14日,星期二*/
CDate dateKnown;
dateKnown.iYear
= 2011;
dateKnown.iMonth
= 7;
dateKnown.iDay
= 12;
int iKnownDayOfWeek = 2;

CDate dateUnknown;

/*2016年8月15日,星期一*/
dateUnknown.iYear
= 2016;
dateUnknown.iMonth
= 8;
dateUnknown.iDay
= 15;
cout
<<GetDayOfWeek(dateKnown, iKnownDayOfWeek, dateUnknown)<<endl;

/*1999年1月1日,星期五*/
dateUnknown.iYear
= 1999;
dateUnknown.iMonth
= 1;
dateUnknown.iDay
= 1;
cout
<<GetDayOfWeek(dateKnown, iKnownDayOfWeek, dateUnknown)<<endl;
}
 
 


 

 

posted on 2011-07-12 22:51  闲云鹤  阅读(1497)  评论(0编辑  收藏  举报