c ++中的年持续时间算法

时间:2012-06-04 08:00:58

标签: c++ algorithm duration

我正在制作一个需要一年的持续时间(time_t)的程序。

在其他方面,time_t DD / MM / YYYY +持续时间= time_t DD / MM / YYYY + 1

所以它可能并不总是365天(并且2012年2月29日将成为28/02/2013)

这是我附带的算法:

if YEAR is leap than
    if we are before the 29th feb' than return 365+1 days
    else if we are the 29th feb' than return 365-1 days
    else return 365 days
else if YEAR+1 is leap than
    if we are before or the 28th feb' than return 365 days
    else return 365+1 days
else return 365 days

这里,一天是60 * 60 * 24秒

此算法似乎有效。但我想知道是否有其他方法可以做到这一点,没有所有这些条件,只有2个可能的返回值,或只是一些“技巧”来优化事物。

我尝试从tm_year增加struct tm,如下所示:

// t is the input time_t
struct tm Tm (*localtime(&t));
if (Tm.tm_mon == 2 && Tm.tm_mday == 29) --Tm.tm_mday;
++Tm.tm_year;
return mktime(&Tm) - t;

但结果不是我想要的,我得了-1小时,或者-25 ......

我想这是因为一年不是365 * 24 * 60 * 60。

3 个答案:

答案 0 :(得分:5)

我会使用Boost,因为它已经实现了你想要的东西:

#include <iostream>
#include <boost/date_time/gregorian/gregorian_types.hpp>
namespace date = boost::gregorian;

int main() {
   date::date_period dp(date::date(2012, 6, 4), date::date(2013, 6, 4));
   long days = dp.length().days();
   std::cout << "Days between dates: " << days << std::endl;

}

如果你想要更高的精确度,那么你也可以使用Boost中的posix_time

namespace ptime = boost::posix_time;

...

ptime::ptime t1(date::date(2012, 6, 4), ptime::hours(0));
ptime::ptime t2(date::date(2013, 6, 4), ptime::hours(0));

ptime::time_duration td = t2 - t1;
std::cout << "Milliseconds: " << td.total_milliseconds() << std::endl;

通常以秒为单位测量time_t。因此,您只需要调用td.total_seconds()来获取您要查找的值。

答案 1 :(得分:2)

if YEAR is leap than
    if we are before the 29th feb' than return 365+1 days
    else if we are the 29th feb' than return 365-1 days
    else return 365 days
else if YEAR+1 is leap than
    if we are before or the 28th feb' than return 365 days
    else return 365+1 days
else return 365 days

简化为:

if (YEAR is leap)
    if (< 29th Feb) return 365+1
    if (= 29th Feb) return 365-1
else if (YEAR+1 is leap)
    if (> 29th Feb) return 365+1

return 365

但你为什么要这样做呢?拥有可读代码比“技巧”优化要好得多。

正如@betabandido建议的那样,像date(year+1, mon, day) - date(year, mon, day)这样的东西会更简单,更具可读性,能够处理闰年,闰秒和September missing 11 days

答案 2 :(得分:0)

太阳年的长度不是固定的数字。 Gregorian calendar发明了一种补偿闰年的方法,这种方法并不完全准确。这就是“如果它可以被4整除,那么一年是闰年,除非它可以被100整除,但如果可以被400整除则再次跳跃。

我们在伊朗有一个more precise calendar,其中岁月改变了第二个地球绕太阳转了一圈。在同一个链接中,您可以看到平均太阳年为365.2422天,春分之间的平均间隔为365.2424天。

this link中,有关太阳年(热带年)的长度的详细信息,以秒为单位。