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.

Thanks in advance.
LVL 2
agriggsAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
ZoppoConnect With a Mentor 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 )
 {
  Add( 0, months );
 }

 inline void AddYears( int years )
 {
  Add( years, 0 );
 }
};



...
CMyDate date;
CString t;

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

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

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

date.AddMonths( 123 );
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
 
jhanceCommented:
>>For example, adding 1 month to February 1st adds 28 days,
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
 
agriggsAuthor 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
The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

 
real_guardianCommented:
MFC does not contain such class. So you must to write your own code to do it
0
 
ZoppoCommented:
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
 
agriggsAuthor 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:

?dateadd("m", 2, #1/31/2001#)
3/31/2001
?dateadd("m", 1, #1/31/2001#)
2/28/2001
?dateadd("yyyy", 1, #2/29/2000#)
2/28/2001
0
 
agriggsAuthor Commented:
I guess I shouldn't penalize you because of the limitations in MFC.  I will try the derived date class.
0
 
zmagyarCommented:
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
 
zmagyarCommented:
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.

All Courses

From novice to tech pro — start learning today.