[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1473
  • Last Modified:

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.
0
agriggs
Asked:
agriggs
  • 3
  • 2
  • 2
  • +2
1 Solution
 
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
 
real_guardianCommented:
MFC does not contain such class. So you must to write your own code to do it
0
[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

 
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
 
ZoppoCommented:
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
 
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

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 3
  • 2
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now