我如何正确地将天数添加到给定日期?

How do i correctly add days to given date?

我为存储日期的 class 创建了这个运算符,它应该添加给定的日期天数并将其转换回人类格式

CDate CDate::operator+(const int x)
{
    time_t t;
    struct tm tmp = {0};
    struct tm newtime = {0};
    tmp.tm_year = timeinfo.tm_year;
    tmp.tm_mon = timeinfo.tm_mon;
    tmp.tm_mday = timeinfo.tm_mday + x;
    t = mktime(&tmp);
    newtime = *(localtime(&t));
    return CDate(newtime.tm_year,newtime.tm_mon,newtime.tm_mday);
}

问题是它计算的日期比它应该的高 3 天

具体问题是,我的日期是 2000-01-02(年-月-日),我尝试添加 1500 天,预期结果是 2004-02-10,但我得到的是 2004-02-13

check

我做错了什么?

我的代码: http://pastebin.com/wLxzTe3W

这是给日期加上天数的算法。

根据日期计算天数。

function g(y,m,d)

   m = (m + 9) % 12

   y = y - m/10

   return 365*y + y/4 - y/100 + y/400 + (m*306 + 5)/10 + ( d - 1 )

要加号。日期中的天数->

g(y2,m2,d2) + no_of_days

在此之后,您可以将日期转换回日期。

    function d(g)
y = (10000*g + 14780)/3652425
ddd = g - (365*y + y/4 - y/100 + y/400)
if (ddd < 0) then
 y = y - 1
 ddd = g - (365*y + y/4 - y/100 + y/400)
 endif
mi = (100*ddd + 52)/3060
mm = (mi + 2)%12 + 1
y = y + (mi + 2)/12
dd = ddd - (mi*306 + 5)/10 + 1
return y, mm, dd

你有两个错误。

首先,传递给 mktime 的 tm 是无效的:年份不应该像 2000 那样是绝对年份,而是与 1900 年的差异,即。 100 表示 2000。更正此问题后,我得到 2004-02-12 作为结果(既不是 2004-02-13 也不是 2004-02-10)。

(在我的电脑上,程序(没有任何更改)就崩溃了:mktime returns -1,localtime 无法处理它并且 returns 一个无效的指针,用于同一行...)

其次,在同一个结构中,日期可能是1-31,但月份只有0-11(而不是1-12)。您的 2000-01-02 是二月的第二天,而不是一月。

知道这一点,结果是正确的(我会写完整的年份,但月份从 0 开始):
1500 天添加到 2000-01-02
2000 年有 366 天(闰年),我们不需要一月和二月的第一天:
2000-01-02 + (366-31-1) 天= 2001-00-01, 1166 天加左
再过365天2002-00-01,还剩801天
再过365天补2003-00-01,再补436天
再过365天赚2004-00-01,再赚71天就剩
又一月 31 使 2004-01-01,还有 40 天加左
闰二月再过292004-02-01,再剩11天
另外 11 个添加使得 2004-02-12

仔细阅读http://www.cplusplus.com/reference/ctime/tm/