# Date arithmetic in MFC greater than a month

Does anyone know how to conduct date arithmetic in MFC with differences greater than a month or a year.  The CDateTimeSpan object is useless in this context because the absolute amount of time in the span is dependent upon what the starting date is.  For example, adding 1 month to February 1st adds 28 days, while adding 1 month to March 1st adds 31 days, of course.

What I want to do is get the date of 1 year ago today.  I tried subtracting 1 from the year, and otherwise loading the current date into a COleDateTime object.  That won't work on February 29th, the resultant date is invalid.

I'm sure there's a simple way or something I haven't thought of.

LVL 2
###### Who is Participating?

x

Commented:
Well, you could do something like this:
class CMyDate : public COleDateTime
{
public:
inline void Add( int years, int months )
{
int y = GetYear();
int m = GetMonth();
int d = GetDay();

m += months;
y += years + m / 12;
m = m % 12;

SetDate( y, m, d );

while ( GetStatus() != valid )
SetDate( y, m, --d );
}

inline void AddMonths( int months )
{
}

inline void AddYears( int years )
{
}
};

...
CMyDate date;
CString t;

date.SetDate( 1996, 1, 31 );
t = date.Format();
cout << LPCTSTR( t ) << endl;

t = date.Format();
cout << LPCTSTR( t ) << endl;

t = date.Format();
cout << LPCTSTR( t ) << endl;

t = date.Format();
cout << LPCTSTR( t ) << endl;
...

Output:
31.01.1996
29.02.1996
28.02.1997
28.05.2007

hope that helps,

ZOPPO
0

Commented:
while adding 1 month to March 1st adds 31 days, of course.

What would you expect it to do?  You asked it to add 1 month.  So just HOW LONG IS A MONTH?  Hmmm, it depends on the month, doesn't it??

0

Author Commented:
What I am saying is that the CDateTimeSpan object supports adding or subtracting a number of days, hours, minutes, or seconds.  But what if you want to add or subtract months or years?  What do you do then?  I guess I would like a dateadd function like in VB.  I can't find one in any of the resources I have consulted.
0

Commented:
MFC does not contain such class. So you must to write your own code to do it
0

Commented:
I think that it simply doesn't make sense to use units like months and years for date
calculation. For example if you add a month to 31.01, what should be the result? 28.02
(or 29.02 if exist for that year)? And if you add a month to the result the new result will
be 28.03 (or 29.03) which I think differs from the expected result when adding two
months to 31.01 (which should be 31.03).

To avoid invalid dates use the COleDateTime::GetStatus() function.

ZOPPO
0

Author Commented:
I agree that technically there is some ambiguity associated with these date calculations.  However, that doesn't mean that users don't expect to see them in their applications.  Look at Windows Explorer, hit the search button, and click on the date option.  One of the options it gives you is "modified in the last x months."

I want one in MFC that works like the one in VB:

3/31/2001
2/28/2001
2/28/2001
0

Author Commented:
I guess I shouldn't penalize you because of the limitations in MFC.  I will try the derived date class.
0

Commented:
Be careful with the above code if you are dealing with negative operands (e.g. -3 months) as it may result an infinitive loop in that case.
0

Commented:
to get it working with negative numbers you ned to change the function like

inline void Add( int years, int months )
{
int y = GetYear();
int m = GetMonth();
int d = GetDay();

m += months;
y += years + m / 12;
m = m % 12;

if (m <= 0)
{
m= 12 + m;
y--;
}

SetDate( y, m, d );

while ( GetStatus() != valid )
SetDate( y, m, --d );
}
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.