Print Page | Close Window

ShiftDate_Month

Printed From: Codejock Forums
Category: Codejock Products
Forum Name: Calendar
Forum Description: Topics Related to Codejock Calendar
URL: http://forum.codejock.com/forum_posts.asp?TID=13522
Printed Date: 28 September 2024 at 5:02pm
Software Version: Web Wiz Forums 12.04 - http://www.webwizforums.com


Topic: ShiftDate_Month
Posted By: zitz
Subject: ShiftDate_Month
Date 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?



Replies:
Posted By: mdoubson
Date 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.


-------------
Mark Doubson, Ph.D.


Posted By: zitz
Date 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


Posted By: mdoubson
Date 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
}


-------------
Mark Doubson, Ph.D.


Posted By: mdoubson
Date 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!


-------------
Mark Doubson, Ph.D.



Print Page | Close Window

Forum Software by Web Wiz Forums® version 12.04 - http://www.webwizforums.com
Copyright ©2001-2021 Web Wiz Ltd. - https://www.webwiz.net