简体   繁体   English

提升local_date_time数学错误?

[英]boost local_date_time math wrong?

I'm using Boost's datetime library in my project. 我在项目中使用Boost的datetime库 I was very happy when I discovered that it has time duration types for hours, days, months, years, etc, and they change their value based on what you're adding them to (ie adding 1 month advances the month part of the date, it doesn't just add 30 days or somesuch). 当我发现它的持续时间类型为小时,天,月,年等时,我感到非常高兴,并且它们会根据您添加的时间来更改其值(即,将日期的月份部分提前1个月) ,而不仅仅是增加30天之类的时间)。 I thought this property held for the days type, but I decided to test it before I put it into production... 以为这个属性适合天数类型,但是我决定在投入生产之前对其进行测试...

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());
}

Above you'll see my CPPUNIT unit test. 在上方,您将看到我的CPPUNIT单元测试。 It fails at the indicated line with 2, which is what I would expect if days() merely added 24 hours, instead of 1 logical day (since the DST transition causes 2010-03-14 to be 23 hours long in EST). 它在指示的行2处失败,这是如果days()仅增加24小时而不是1个逻辑天,那是我所期望的(因为DST过渡导致2010-03-14在EST中的时间为23小时)。

Am I doing something wrong? 难道我做错了什么? Is this a bug? 这是一个错误吗? Did I just completely misunderstand the design goal of the library with respect to this sort of math? 我是否就这种数学完全误解了库的设计目标?

I think the problem is in the asker's conception of what a day is. 我认为问题出在问问者对一天是什么的概念。 He wants it to be a 'date' day here, rather than 24 hours, but that is not a reasonable thing to ask for. 他希望今天在这里是“约会”的日子,而不是24小时,但这并不是一个合理的要求。

If working in local time, one is bound to encounter peculiar effects. 如果在当地时间工作,那一定会遇到奇特的影响。 For example, what do you expect to happen if, in a timezone that puts clocks forward from 1am to 2am, if your local time 'add date day' calculation should set the (non existent) 1.30am on the relevant Sunday morning? 例如,如果在将时钟从凌晨1点推迟到凌晨2点的时区中,如果您的本地时间“添加日期日”计算应在相关的周日上午将凌晨1点(不存在)设置为1.30,会发生什么情况?

A time calculation has got to move forward 24 hours - it must operate on the underlying UTC time. 一时间计算得到了前进24小时-它必须在底层UTC时间操作。

To make the 'jump one day' calculation as described, work with Boost's date type, and only add in the time-of-day as the final action. 要按照上述说明进行“一日跳转”计算,请使用Boost的日期类型,并仅将一天中的时间添加为最终操作。

The business of being able to advance a month is quite different, because, unlike a day, a calendar month has no specific meaning as a duration. 可以提前一个月的业务是完全不同的,因为与一天不同,日历月没有特定的含义作为持续时间。 And it causes troubles too: if you advance one calendar month from 31st January, and then go back one calendar month, what date do you end up with? 这也会带来麻烦:如果您从1月31日开始提前一个日历月,然后再返回一个日历月,那么您将在哪个日期结束?

Instead of adding the date_duration object days , you should create a boost::posix_time::time_duration object and add this to your local time , like so: boost::posix_time::time_duration td ( 24 , 0 , 0 , 0 ) ; 与其添加date_duration对象的天数, 不如创建一个boost :: posix_time :: time_duration对象并将其添加到本地时间,就像这样:boost :: posix_time :: time_duration td(24,0,0,0); //24 hours, 0 minutes, seconds, nano boost::local_time::local_date_time later = now + td ; // 24小时,0分钟,秒,nano boost :: local_time :: local_date_time以后= now + td; //assuming that now is your starting //local_date_time , 2010-3-14 //later will now be a local date_time object that takes full account of DST ! //假设现在是您的开始// local_date_time,2010-3-14 //以后将是一个本地date_time对象,它充分考虑了DST!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM