повысить local_date_time математика неправильно? - PullRequest
8 голосов
/ 11 февраля 2010

Я использую библиотеку даты и времени Boost в моем проекте. Я был очень счастлив, когда обнаружил, что у него есть типы продолжительности времени для часов, дней, месяцев, лет и т. Д., И они меняют свое значение в зависимости от того, к чему вы их добавляете (т.е. добавление на 1 месяц опережает месячную часть даты , это не просто добавить 30 дней или около того). Я думал, что это свойство относится к типу дней, но я решил проверить его, прежде чем запустить в производство ...

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 логического дня (поскольку переход по летнему времени приводит к тому, что 2010-03-14 в EST будет длиться 23 часа).

Я что-то не так делаю? Это ошибка? Я только что совершенно неправильно понял цель разработки библиотеки в отношении такого рода математики?

Ответы [ 2 ]

5 голосов
/ 16 февраля 2010

Мне кажется, проблема в том, что спрашивающий понимает, что такое день. Он хочет, чтобы это был день «свидания», а не 24 часа, но просить об этом не разумно.

Если вы работаете по местному времени, вы обязательно столкнетесь с особыми эффектами. Например, что вы ожидаете, если в часовом поясе, который переводит часы вперед с 1 до 2 часов, если при подсчете вашего дополнительного времени по местному времени будет установлено (не существует) 1.30 в соответствующее воскресное утро?

Расчет времени имеет , получил для продвижения вперед на 24 часа - он должен работать в основное время UTC.

Чтобы выполнить вычисление «Прыжок за один день», как описано, работайте с типом даты Boost и добавляйте только время дня в качестве последнего действия.

Дело в том, чтобы продвигать месяц совершенно иначе, потому что, в отличие от дня, календарный месяц не имеет конкретного значения как продолжительность. И это тоже доставляет неприятности: если вы продвинетесь на один календарный месяц с 31 января, а затем вернетесь на один календарный месяц, с какой датой вы закончите?

0 голосов
/ 11 февраля 2010

Вместо добавления date_duration объектов дней, вы должны создать объект boost :: posix_time :: time_duration и добавить его к вашему местному времени, например так: boost :: posix_time :: time_duration td (24, 0, 0, 0); // 24 часа, 0 минут, секунды, нано boost :: local_time :: local_date_time позже = сейчас + td; // при условии, что сейчас ваш старт // local_date_time, 2010-3-14 // позже теперь будет локальный объект date_time, который полностью учитывает DST!

...