Codejock Forums Homepage
Forum Home Forum Home > Codejock Products > Visual C++ MFC > Calendar
  New Posts New Posts RSS Feed - ShiftDate_Month
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

ShiftDate_Month

 Post Reply Post Reply
Author
Message
zitz View Drop Down
Senior Member
Senior Member


Joined: 05 October 2008
Status: Offline
Points: 112
Post Options Post Options   Thanks (0) Thanks(0)   Quote zitz Quote  Post ReplyReply Direct Link To This Post Topic: ShiftDate_Month
    Posted: 28 February 2009 at 2:30am
Hello. I use Xtreme ToolkitPro v13.0.0

AFX_INLINE BOOL CXTPCalendarUtils::ShiftDate_Month(COleDateTime &refDate, int nMonthCount)
{
    SYSTEMTIME sysDate;
    if (!GETASSYSTEMTIME_DT(refDate, sysDate))
        return FALSE;

    int nYearNew = sysDate.wYear + nMonthCount / 12;
    int nMonthNew = sysDate.wMonth + nMonthCount % 12;

    if (nMonthNew > 12)
    {
        nMonthNew -= 12 * (nMonthCount / abs(nMonthCount));
        nYearNew++;
    }
    else if (nMonthNew <= 0)
    {
        nYearNew--;
        nMonthNew += 12;

        ASSERT(nMonthNew >= 1 && nMonthNew <= 12);
    }

    return COleDateTime::valid == refDate.SetDate(nYearNew, nMonthNew, 1);
}

Function works wrong at release (Visual C++ 6.0) for nMonthCount = -1, I think because inline

For what?
nMonthNew -= 12 * (nMonthCount / abs(nMonthCount));
It is unnecessary here i think.
nMonthCount / abs(nMonthCount) == 1 always, or not?
Back to Top
mdoubson View Drop Down
Senior Member
Senior Member
Avatar

Joined: 17 November 2008
Status: Offline
Points: 1705
Post Options Post Options   Thanks (0) Thanks(0)   Quote mdoubson Quote  Post ReplyReply Direct Link To This Post Posted: 28 February 2009 at 10:19am
I will check this - sorry - old strange class - i already fixed here serious bugs recently. But there was no complains on this function.
 
Btw - n / abs(n) can also be -1 and compiler shoud understand it.
Back to Top
zitz View Drop Down
Senior Member
Senior Member


Joined: 05 October 2008
Status: Offline
Points: 112
Post Options Post Options   Thanks (0) Thanks(0)   Quote zitz Quote  Post ReplyReply Direct Link To This Post Posted: 28 February 2009 at 1:14pm
Originally posted by mdoubson mdoubson wrote:

Btw - n / abs(n) can also be -1 and compiler shoud understand it.

No, it can't. If nMountCount < 0 then
if (nMonthNew > 12) <---- FALSE
I think it was without "if" in former times, for example
 int nYearNew = sysDate.wYear + nMonthCount / 12;
int nMonthNew = sysDate.wMonth + nMonthCount % 12;
 nMonthNew -= 12 * (nMonthCount / abs(nMonthCount));
 nYearNew += nMonthCount / abs(nMonthCount);
ASSERT(nMonthNew >= 1 && nMonthNew <= 12);
and if nMountCount == 0 --> crash
Back to Top
mdoubson View Drop Down
Senior Member
Senior Member
Avatar

Joined: 17 November 2008
Status: Offline
Points: 1705
Post Options Post Options   Thanks (0) Thanks(0)   Quote mdoubson Quote  Post ReplyReply Direct Link To This Post Posted: 28 February 2009 at 2:18pm
No - I checked SVN - this version identical to Nov 2008 version (Rev 12.1)
I can cofirm the bug you found.
this is old code:

AFX_INLINE  BOOL CXTPCalendarUtils::ShiftDate_Month(COleDateTime &refDate, int nMonthCount)
{
 SYSTEMTIME sysDate;
 if (!GETASSYSTEMTIME_DT(refDate, sysDate))
  return FALSE;

 int nYearNew = sysDate.wYear + nMonthCount / 12;
 int nMonthNew = sysDate.wMonth + nMonthCount % 12;

 if (nMonthNew > 12)
 {
     nMonthNew -= 12 * (nMonthCount / abs(nMonthCount));
     nYearNew++;
 }
 else if (nMonthNew <= 0)
 {
     nYearNew--;
     nMonthNew += 12;

     ASSERT(nMonthNew >= 1 && nMonthNew <= 12);
 }

 return COleDateTime::valid == refDate.SetDate(nYearNew, nMonthNew, 1);

}

Unfortunately % operator in MS doing not proper modulo arithm - in math it suppose to give you positive result or nul - in MS - NOT:

COleDateTime refDate(2000,1,1,0,0,0);

SYSTEMTIME sysDate;

if (GETASSYSTEMTIME_DT(refDate, sysDate))

{

int nYearNew, nMonthNew, nMonthCount;

for (nMonthCount = -20; nMonthCount < 20; nMonthCount++)

{
    //modulo operation debug:
nYearNew = sysDate.wYear + (sysDate.wMonth + nMonthCount) / 12;

nMonthNew = 1 + ((int) (sysDate.wMonth) + nMonthCount - 1) % 12;

===> it give nMonthNew = -7 in first loop step!
 
    //this is old code debug:

nYearNew = sysDate.wYear + nMonthCount / 12;

nMonthNew = sysDate.wMonth + nMonthCount % 12;

nMonthNew -= 12 * (nMonthCount / abs(nMonthCount));

nYearNew += nMonthCount / abs(nMonthCount);

ASSERT(nMonthNew >= 1 && nMonthNew <= 12);

      this code give ASSERTION with nMonthNew = 13
}
Back to Top
mdoubson View Drop Down
Senior Member
Senior Member
Avatar

Joined: 17 November 2008
Status: Offline
Points: 1705
Post Options Post Options   Thanks (0) Thanks(0)   Quote mdoubson Quote  Post ReplyReply Direct Link To This Post Posted: 28 February 2009 at 5:42pm
The formula is very simple:

AFX_INLINE BOOL CXTPCalendarUtils::ShiftDate_Month(COleDateTime &refDate, int nMonthCount)

{

int nYearOld = refDate.GetYear();

int nMonthOld = refDate.GetMonth();

int nYearNew = nYearOld + (-12 + nMonthOld + nMonthCount) / 12;

int nMonthCalc = nMonthOld + nMonthCount - 1;

if (nMonthCalc < 0)

nMonthCalc = 12 * (-nMonthCalc) + nMonthCalc;

int nMonthNew = 1 + nMonthCalc % 12;

return COleDateTime::valid == refDate.SetDate(nYearNew, nMonthNew, 1);

}

I already update SVN. Thank you!
Back to Top
 Post Reply Post Reply
  Share Topic   

Forum Jump Forum Permissions View Drop Down

Forum Software by Web Wiz Forums® version 12.04
Copyright ©2001-2021 Web Wiz Ltd.

This page was generated in 0.141 seconds.