Вопрос

Я обнаружил ошибку в старой программе C ++ MFC, которая вычисляет смещение (в днях) для заданной даты от фиксированной базовой даты. Мы увидели результаты, которые по какой-то причине были единичными, и я отследил их там, где первоначальный программист использовал метод CTimeSpan.GetDays (). Согласно документации :

  

Обратите внимание, что переход на летнее время может привести к тому, что GetDays выдаст потенциально неожиданный результат. Например, когда действует летнее время, GetDays сообщает количество дней между 1 апреля и 1 мая как 29, а не 30, поскольку один день в апреле сокращается на час и, следовательно, не считается полным днем.

Мое предлагаемое исправление - использовать (obj.GetTotalHours () + 1) / 24 . Я думаю, что это покроет все проблемы, так как это пакетная работа, которая выполняется примерно в одно и то же время каждый день, но я подумал, что перед тем, как ее реализовать, я бы попросил умных людей, если это возможно, найти лучший способ.

Это всего лишь побочный вопрос, но мне также любопытно, как это можно было бы решить, если бы программа могла быть запущена в любое время.

Это было полезно?

Решение

Ваше исправление отлично работает, чтобы получить количество целых 24-часовых периодов между двумя периодами, если события происходят в одно и то же время каждый день. В противном случае это "+ 1" в выражении может привести к ошибке off-by-one.

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

CTime startDay(start.GetYear(), start.GetMonth(), start.GetDay(), 0, 0, 0);
CTime finishDay(finish.GetYear(), finish.GetMonth(), finish.GetDay(), 0, 0, 0);
int days = ((finishDay - startDay).GetTotalHours() + 1) / 24;

Другие советы

Незначительное изменение предложенного Марком, и оно работает без использования округления: просто добавьте еще один нулевой параметр в конструктор CTime . Это заставляет оба раза быть в стандартное время (не летнее время). Значением по умолчанию для этого параметра является -1, что означает «Автоматически вычислять, если действует летнее время».

// Discard hours, minutes, seconds, and daylight savings time
CTime startDay(start.GetYear(), start.GetMonth(), start.GetDay(), 0, 0, 0, 0);
CTime endDay(end.GetYear(), end.GetMonth(), end.GetDay(), 0, 0, 0, 0);

// Get number of days apart
CTimeSpan span = endDay - startDay;
int nDays = span.GetDays();

Протестировано и работает.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top