diff --git a/dlls/oleaut32/tests/vartest.c b/dlls/oleaut32/tests/vartest.c index 377a8472b5b..34f0e3f4805 100644 --- a/dlls/oleaut32/tests/vartest.c +++ b/dlls/oleaut32/tests/vartest.c @@ -1652,17 +1652,20 @@ static void test_VarDateFromUdate(void) UD2T(30,12,1899,0,0,0,999,0,0,0,S_OK,0.0); /* Ignore milliseconds */ UD2T(1,1,1980,18,1,16,0,2,1,0,S_OK,29221.75087962963); /* 6:18:02 PM */ + UD2T(1,300,1980,18,1,16,0,2,1,0,S_OK,38322.75087962963); /* Test fwdrolled month */ + UD2T(300,1,1980,18,1,16,0,2,1,0,S_OK,29520.75087962963); /* Test fwdrolled days */ UD2T(0,1,1980,42,1,16,0,2,1,0,S_OK,29221.75087962963); /* Test fwdrolled hours */ UD2T(1,1,1980,17,61,16,0,2,1,0,S_OK,29221.75087962963); /* Test fwdrolled minutes */ UD2T(1,1,1980,18,0,76,0,2,1,0,S_OK,29221.75087962963); /* Test fwdrolled seconds */ + UD2T(1,-300,1980,18,1,16,0,2,1,0,S_OK,20059.75087962963); /* Test backrolled month */ + UD2T(-300,1,1980,18,1,16,0,2,1,0,S_OK,28920.75087962963); /* Test backrolled days */ UD2T(3,1,1980,-30,1,16,0,2,1,0,S_OK,29221.75087962963); /* Test backrolled hours */ UD2T(1,1,1980,20,-119,16,0,2,1,0,S_OK,29221.75087962963); /* Test backrolled minutes */ UD2T(1,1,1980,18,3,-104,0,2,1,0,S_OK,29221.75087962963); /* Test backrolled seconds */ UD2T(1,12001,-1020,18,1,16,0,0,0,0,S_OK,29221.75087962963); /* Test rolled year and month */ UD2T(1,-23,1982,18,1,16,0,0,0,0,S_OK,29221.75087962963); /* Test backrolled month */ - todo_wine UD2T(-59,3,1980,18,1,16,0,0,0,0,S_OK,29221.75087962963); /* Test backrolled days */ + UD2T(-59,3,1980,18,1,16,0,0,0,0,S_OK,29221.75087962963); /* Test backrolled days */ todo_wine UD2T(1,1,0,0,0,0,0,0,0,0,S_OK,36526); /* Test zero year */ - UD2T(0,0,1980,0,0,0,0,0,0,0,S_OK,29189); /* Test zero day and month */ UD2T(0,1,1980,0,0,0,0,2,1,0,S_OK,29220.0); /* Test zero day = LastDayOfMonth */ UD2T(-1,1,1980,18,1,16,0,0,0,0,S_OK,29219.75087962963); /* Test day -1 = LastDayOfMonth - 1 */ diff --git a/dlls/oleaut32/variant.c b/dlls/oleaut32/variant.c index dabe7464ced..a2a5bd88ad5 100644 --- a/dlls/oleaut32/variant.c +++ b/dlls/oleaut32/variant.c @@ -1154,64 +1154,34 @@ static HRESULT VARIANT_RollUdate(UDATE *lpUd) iMinute = iMinute % 60; iDay += (iHour - (iHour % 24)) / 24; iHour = iHour % 24; - /* FIXME: Roll Days */ iYear += (iMonth - (iMonth % 12)) / 12; iMonth = iMonth % 12; + if (iMonth<=0) {iMonth+=12; iYear--;} + while (iDay > days[iMonth]) + { + if (iMonth == 2 && IsLeapYear(iYear)) + iDay -= 29; + else + iDay -= days[iMonth]; + iMonth++; + iYear += (iMonth - (iMonth % 12)) / 12; + iMonth = iMonth % 12; + } + while (iDay <= 0) + { + iMonth--; + if (iMonth<=0) {iMonth+=12; iYear--;} + if (iMonth == 2 && IsLeapYear(iYear)) + iDay += 29; + else + iDay += days[iMonth]; + } if (iSecond<0){iSecond+=60; iMinute--;} if (iMinute<0){iMinute+=60; iHour--;} if (iHour<0) {iHour+=24; iDay--;} - if (iDay<0) - { - iDay+=days[iMonth]; - iMonth--; - if (iMonth == 2 && IsLeapYear(iYear)) - iDay++; - } - if (iMonth<=0) {iMonth+=12; iYear--;} if (iYear<0) iYear+=2000; - if (!lpUd->st.wDay) - { - /* Roll back the date one day */ - if (lpUd->st.wMonth == 1) - { - /* Roll back to December 31 of the previous year */ - lpUd->st.wDay = 31; - lpUd->st.wMonth = 12; - lpUd->st.wYear--; - } - else - { - lpUd->st.wMonth--; /* Previous month */ - if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear)) - lpUd->st.wDay = 29; /* February has 29 days on leap years */ - else - lpUd->st.wDay = days[lpUd->st.wMonth]; /* Last day of the month */ - } - } - else if (lpUd->st.wDay > 28) - { - int rollForward = 0; - - /* Possibly need to roll the date forward */ - if (iMonth == 2 && IsLeapYear(iYear)) - rollForward = iDay - 29; /* February has 29 days on leap years */ - else - rollForward = iDay - days[iMonth]; - - if (rollForward > 0) - { - iDay = rollForward; - iMonth++; - if (iMonth > 12) - { - iMonth = 1; /* Roll forward into January of the next year */ - iYear++; - } - } - } - lpUd->st.wYear = iYear; lpUd->st.wMonth = iMonth; lpUd->st.wDay = iDay;