提升local_date_time数学错误?

时间:2010-02-11 15:26:35

标签: c++ datetime boost date-math

我在我的项目中使用Boost's datetime library。当我发现它有持续时间类型的小时,天,月,年等时,我感到非常高兴,并且它们会根据您添加它们的内容来更改它们的值(即,在月份的一部分中添加1个月的预付款) ,它不只是添加30天或某些)。我这个属性为days类型保留了,但我决定在将它投入生产之前测试它...

local_date_time t1(date(2010, 3, 14), hours(1), easternTime, false); // 1am on DST transition date

{
    CPPUNIT_ASSERT_EQUAL(greg_year(2010), t1.local_time().date().year());
    CPPUNIT_ASSERT_EQUAL(greg_month(3), t1.local_time().date().month());
    CPPUNIT_ASSERT_EQUAL(greg_day(14), t1.local_time().date().day());
    CPPUNIT_ASSERT_EQUAL(1L, t1.local_time().time_of_day().hours());
    CPPUNIT_ASSERT_EQUAL(0L, t1.local_time().time_of_day().minutes());
    CPPUNIT_ASSERT_EQUAL(0L, t1.local_time().time_of_day().seconds());
}

t1 += days(1); // the time in EST should now be 1am on the 15th
{
    CPPUNIT_ASSERT_EQUAL(greg_year(2010), t1.local_time().date().year());
    CPPUNIT_ASSERT_EQUAL(greg_month(3), t1.local_time().date().month());
    CPPUNIT_ASSERT_EQUAL(greg_day(15), t1.local_time().date().day());
    CPPUNIT_ASSERT_EQUAL(1L, t1.local_time().time_of_day().hours()); // fails, returns 2
    CPPUNIT_ASSERT_EQUAL(0L, t1.local_time().time_of_day().minutes());
    CPPUNIT_ASSERT_EQUAL(0L, t1.local_time().time_of_day().seconds());
}

上面你会看到我的CPPUNIT单元测试。它在指示的2行失败,如果days()仅增加24小时而不是1逻辑日(因为DST转换导致2010-03-14在EST中长达23小时),这就是我所期望的。 / p>

我做错了吗?这是一个错误吗?在这种数学方面,我是否完全误解了图书馆的设计目标?

2 个答案:

答案 0 :(得分:5)

我认为问题在于提问者关于一天是什么的概念。他希望这是一个“约会”日,而不是24小时,但这不是一个合理的要求。

如果在当地工作,一定会遇到特殊的影响。例如,如果您在当地时间“添加日期日”计算应该设置(不存在的)相关星期日早晨1点30分的时区,如果在时区从早上1点到凌晨2点放置时钟,您会发生什么?

时间计算 24小时前进 - 它必须在基础UTC时间运行。

要按照描述进行“跳一天”计算,请使用Boost的日期类型,并仅添加时间作为最终操作。

能够推进一个月的业务是完全不同的,因为,与一天不同,一个日历月没有特定含义作为持续时间。它也会带来麻烦:如果你从1月31日开始提前一个日历月,然后又回到一个日历月,那么你最终会在几个月结束?

答案 1 :(得分:0)

您应该创建一个boost :: posix_time :: time_duration对象并将其添加到您当地的时间,而不是添加 date_duration 对象天,如下所示: boost :: posix_time :: time_duration td(24,0,0,0); // 24小时,0分钟,秒,纳米 boost :: local_time :: local_date_time later = now + td; //假设现在是你的开始// local_date_time,2010-3-14 //稍后将成为本地date_time对象,它充分考虑了DST!