tags:

views:

497

answers:

2

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.

+1  A: 

This seems like a reasonable fix. I don't know what else you would do.

Oh, I'm sorry - I didn't see the bit at the end about the "smart people".

MusiGenesis
Don't worry: you qualify ;)
Joel Coehoorn
BTW: I'll upvote this in a little while. I want to wait so it stays on the 'unanswered' view a little longer.
Joel Coehoorn
My reputation as a reputation whore precedes me!
MusiGenesis
+1  A: 

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;
Mark Ransom
That makes sense: 0 out the time portion and then integer division will handle the extra hour when daylight savings changes
Joel Coehoorn
Incidently: the code was already zeroing out the time.
Joel Coehoorn