CTimeSpan.GetDays () и переход на летнее время - PullRequest
4 голосов
/ 28 октября 2008

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

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

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

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

Ответы [ 2 ]

2 голосов
/ 28 октября 2008

Ваше исправление отлично работает, чтобы получить количество целых 24-часовых периодов между двумя периодами, если события происходят в одно и то же время каждый день. В противном случае «+1» в выражении может привести к ошибке «один за другим».

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

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;
0 голосов
/ 01 мая 2013

Незначительное изменение предложенного Марком, и оно работает без использования округления: просто добавьте еще один нулевой параметр в конструктор 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();

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

...