Question

I found in a bug in an old C++ MFC program we have that calculates an offset (in days) for a given date from a fixed base date. We were seeing results that were off by one for some reason, and I tracked it down to where the original programmer had used the CTimeSpan.GetDays() method. According to the documentation:

Note that Daylight Savings Time can cause GetDays to return a potentially surprising result. For example, when DST is in effect, GetDays reports the number of days between April 1 and May 1 as 29, not 30, because one day in April is shortened by an hour and therefore does not count as a complete day.

My proposed fix is to use (obj.GetTotalHours()+1)/24 instead. I think that would cover all the issues since this is a batch job that runs at about the same time every day, but I thought I'd ask the smart people here before implementing it if there might be a better way.

This is just a side issue, but I'm also curious how this would be handled if the program could be run at any time.

Was it helpful?

Solution

Your fix works fine to get the number of whole 24-hour periods between two times - as long as the events occur at the same time each day. Otherwise that "+1" in the expression could lead to an off-by-one error.

Sometimes you don't care what time of day the event occured, you just want to know which day. In that case, you need to zero out the hours, minutes, and seconds, then use your formula:

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;

OTHER TIPS

A minor change to what Mark suggested and it works without any reliance on rounding: Just add one more parameter of zero to the CTime constructor. This forces both times to be in standard time (not daylight savings). The default value for that parameter is -1 which means "Automatically compute if daylight savings time is in effect."

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

Tested and works.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top