您的位置:首页 > 其它

两个日期之间闰年数计算方法探索

2011-02-12 18:52 477 查看
由于一个项目的需要,需要计算两个日期之间的天数,计算天数就涉及到闰年的问题,如何计算两个日期之间的闰年数成为了问题的关键。
虽然使用循环可以很容易的计算出来,如下:
int CountLeapYearByLoop(int nYearS, int nYearE)
{
int nCount = 0;
for(int nYear = nYearS; nYear < nYearE; ++nYear)
{
if (IsLeapYear(nYear))
{
nCount++;
}
}

return nCount;
}


这个算法的时间复杂度是(nYearE-nYearS),显然不适宜年份相差很大的计算。

在网上找了好久,也看到一些算法,但是不能够对应所有的情况,有些算法在年份比较大时,差值就不对了。
今天偶然发现了一个规律,如下:一般情况下,两个日期之间的差值除以4取整,减去重叠的部分,就是它们之间的闰年数,但是,当结束日期的余数减去开始日期的余数需要借位时,闰年数需要加1,开始日期的余数为0的情况,当做4来看。
经过测试,该算法基本正确,算法如下:
int CountYearByModBet(int nYearS, int nYearE, int nBet)
{
int nCount = 0;
int nYearDec = nYearE - nYearS;

int nModS = nYearS%nBet;
int nModE = nYearE%nBet;
int nModD = nYearDec%nBet;

if (nModS == 0 || nModE < nModS)
{
nCount = nYearDec/nBet + 1;
}
else
{
nCount = nYearDec/nBet;
}

return nCount;
}

int CountLeapYear(int nYearS, int nYearE)
{
int nCount = 0;

nCount = CountYearByModBet(nYearS, nYearE, 4)
- CountYearByModBet(nYearS, nYearE, 100)
+ CountYearByModBet(nYearS, nYearE, 400);

return nCount;
}


完整的算法和测试用例如下:
#include <iostream>

bool IsLeapYear(int nYear)
{
if ((nYear%400 == 0) || ((nYear%100 != 0) && (nYear%4 == 0)))
{
return true;
}
else
{
return false;
}
}

int CountYearByModBet(int nYearS, int nYearE, int nBet) { int nCount = 0; int nYearDec = nYearE - nYearS; int nModS = nYearS%nBet; int nModE = nYearE%nBet; int nModD = nYearDec%nBet; if (nModS == 0 || nModE < nModS) { nCount = nYearDec/nBet + 1; } else { nCount = nYearDec/nBet; } return nCount; } int CountLeapYear(int nYearS, int nYearE) { int nCount = 0; nCount = CountYearByModBet(nYearS, nYearE, 4) - CountYearByModBet(nYearS, nYearE, 100) + CountYearByModBet(nYearS, nYearE, 400); return nCount; }

int CountLeapYearByLoop(int nYearS, int nYearE) { int nCount = 0; for(int nYear = nYearS; nYear < nYearE; ++nYear) { if (IsLeapYear(nYear)) { nCount++; } } return nCount; }

int main()
{
std::cout << "leap year count test " << std::endl;
int nCount = 0;
int nCountEx = 0;
int nYearS = 2001;
int nYearE = 9999;
std::cout << "count the leap year from " << nYearS << " to " << nYearE << std::endl;

std::cout << "count = " << CountLeapYear(nYearS,nYearE) << std::endl;
std::cout << "loop count = " << CountLeapYearByLoop(nYearS,nYearE) << std::endl;

#ifdef _DEBUG
getchar();
#endif

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 测试