Module: wine Branch: master Commit: 1b51c21fb30ee3fa4366d3628d343361e1696ef3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=1b51c21fb30ee3fa4366d3628d...
Author: André Hentschel nerv@dawncrow.de Date: Mon Feb 1 21:26:44 2010 +0100
oleaut32: Rewrite RollUdate to be easier to change and to support more conversions.
---
dlls/oleaut32/tests/vartest.c | 30 ++++++++++----- dlls/oleaut32/variant.c | 81 +++++++++++++++++++++++++++-------------- 2 files changed, 74 insertions(+), 37 deletions(-)
diff --git a/dlls/oleaut32/tests/vartest.c b/dlls/oleaut32/tests/vartest.c index 8d7cf11..377a847 100644 --- a/dlls/oleaut32/tests/vartest.c +++ b/dlls/oleaut32/tests/vartest.c @@ -1639,26 +1639,36 @@ static void test_VarDateFromUdate(void) CHECKPTR(VarDateFromUdate); UD2T(1,1,1980,0,0,0,0,2,1,0,S_OK,29221.0); /* 1 Jan 1980 */ UD2T(2,1,1980,0,0,0,0,3,2,0,S_OK,29222.0); /* 2 Jan 1980 */ + UD2T(2,1,1980,0,0,0,0,4,5,0,S_OK,29222.0); /* 2 Jan 1980 */ UD2T(31,12,1990,0,0,0,0,0,0,0,S_OK,33238.0); /* 31 Dec 1990 */ UD2T(31,12,90,0,0,0,0,0,0,0,S_OK,33238.0); /* year < 100 is 1900+year! */ UD2T(30,12,1899,0,0,0,0,6,364,0,S_OK,0.0); /* 30 Dec 1899 - VT_DATE 0.0 */ UD2T(1,1,100,0,0,0,0,0,0,0,S_OK,-657434.0); /* 1 Jan 100 - Min */ UD2T(31,12,9999,0,0,0,0,0,0,0,S_OK,2958465.0); /* 31 Dec 9999 - Max */ UD2T(1,1,10000,0,0,0,0,0,0,0,E_INVALIDARG,0.0); /* > 31 Dec 9999 => err */ + UD2T(1,1,-10000,0,0,0,0,0,0,0,E_INVALIDARG,0.0);/* < -9999 => err */
UD2T(30,12,1899,0,0,0,0,0,0,0,S_OK,0.0); /* 30 Dec 1899 0:00:00 */ 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 */ - todo_wine UD2T(0,1,1980,42,1,16,0,2,1,0,S_OK,29221.75087962963); /* Test rolled hours */ - todo_wine UD2T(1,1,1980,17,61,16,0,2,1,0,S_OK,29221.75087962963); /* Test rolled minutes */ - todo_wine UD2T(1,1,1980,18,0,76,0,2,1,0,S_OK,29221.75087962963); /* Test rolled seconds */ - todo_wine UD2T(2,1,1980,-6,1,16,0,2,1,0,S_OK,29221.75087962963); /* Test backrolled hours */ - todo_wine UD2T(1,1,1980,19,-59,16,0,2,1,0,S_OK,29221.75087962963); /* Test backrolled minutes */ - todo_wine UD2T(1,1,1980,18,2,-44,0,2,1,0,S_OK,29221.75087962963); /* Test backrolled seconds */ - - UD2T(0,1,1980,0,0,0,0,2,1,0,S_OK,29220.0); /* Rolls back to 31 Dec 1899 */ - UD2T(1,13,1980,0,0,0,0,2,1,0,S_OK,29587.0); /* Rolls fwd to 1/1/1981 */ + UD2T(1,1,1980,18,1,16,0,2,1,0,S_OK,29221.75087962963); /* 6:18:02 PM */ + 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(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 */ + 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 */ + UD2T(1,1,-1,18,1,16,0,0,0,0,S_OK,36161.75087962963); /* Test year -1 = 1999 */ + UD2T(1,-1,1980,18,1,16,0,0,0,0,S_OK,29160.7508796296); /* Test month -1 = 11 */ + UD2T(1,13,1980,0,0,0,0,2,1,0,S_OK,29587.0); /* Rolls fwd to 1/1/1981 */ }
static void test_st2dt(int line, WORD d, WORD m, WORD y, WORD h, WORD mn, diff --git a/dlls/oleaut32/variant.c b/dlls/oleaut32/variant.c index 56ab2b3..dabe746 100644 --- a/dlls/oleaut32/variant.c +++ b/dlls/oleaut32/variant.c @@ -1129,30 +1129,47 @@ static inline double VARIANT_JulianFromDMY(USHORT year, USHORT month, USHORT day static HRESULT VARIANT_RollUdate(UDATE *lpUd) { static const BYTE days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + short iYear, iMonth, iDay, iHour, iMinute, iSecond;
- TRACE("Raw date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth, - lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond); + /* interpret values signed */ + iYear = lpUd->st.wYear; + iMonth = lpUd->st.wMonth; + iDay = lpUd->st.wDay; + iHour = lpUd->st.wHour; + iMinute = lpUd->st.wMinute; + iSecond = lpUd->st.wSecond;
- /* Years < 100 are treated as 1900 + year */ - if (lpUd->st.wYear < 100) - lpUd->st.wYear += 1900; + TRACE("Raw date: %d/%d/%d %d:%d:%d\n", iDay, iMonth, + iYear, iHour, iMinute, iSecond);
- if (!lpUd->st.wMonth) - { - /* Roll back to December of the previous year */ - lpUd->st.wMonth = 12; - lpUd->st.wYear--; - } - else while (lpUd->st.wMonth > 12) + if (iYear > 9999 || iYear < -9999) + return E_INVALIDARG; /* Invalid value */ + /* Years < 100 are treated as 1900 + year */ + if (iYear >= 0 && iYear < 100) + iYear += 1900; + + iMinute += (iSecond - (iSecond % 60)) / 60; + iSecond = iSecond % 60; + iHour += (iMinute - (iMinute % 60)) / 60; + iMinute = iMinute % 60; + iDay += (iHour - (iHour % 24)) / 24; + iHour = iHour % 24; + /* FIXME: Roll Days */ + iYear += (iMonth - (iMonth % 12)) / 12; + iMonth = iMonth % 12; + + if (iSecond<0){iSecond+=60; iMinute--;} + if (iMinute<0){iMinute+=60; iHour--;} + if (iHour<0) {iHour+=24; iDay--;} + if (iDay<0) { - /* Roll forward the correct number of months */ - lpUd->st.wYear++; - lpUd->st.wMonth -= 12; + iDay+=days[iMonth]; + iMonth--; + if (iMonth == 2 && IsLeapYear(iYear)) + iDay++; } - - if (lpUd->st.wYear > 9999 || lpUd->st.wHour > 23 || - lpUd->st.wMinute > 59 || lpUd->st.wSecond > 59) - return E_INVALIDARG; /* Invalid values */ + if (iMonth<=0) {iMonth+=12; iYear--;} + if (iYear<0) iYear+=2000;
if (!lpUd->st.wDay) { @@ -1178,22 +1195,30 @@ static HRESULT VARIANT_RollUdate(UDATE *lpUd) int rollForward = 0;
/* Possibly need to roll the date forward */ - if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear)) - rollForward = lpUd->st.wDay - 29; /* February has 29 days on leap years */ + if (iMonth == 2 && IsLeapYear(iYear)) + rollForward = iDay - 29; /* February has 29 days on leap years */ else - rollForward = lpUd->st.wDay - days[lpUd->st.wMonth]; + rollForward = iDay - days[iMonth];
if (rollForward > 0) { - lpUd->st.wDay = rollForward; - lpUd->st.wMonth++; - if (lpUd->st.wMonth > 12) + iDay = rollForward; + iMonth++; + if (iMonth > 12) { - lpUd->st.wMonth = 1; /* Roll forward into January of the next year */ - lpUd->st.wYear++; + iMonth = 1; /* Roll forward into January of the next year */ + iYear++; } } } + + lpUd->st.wYear = iYear; + lpUd->st.wMonth = iMonth; + lpUd->st.wDay = iDay; + lpUd->st.wHour = iHour; + lpUd->st.wMinute = iMinute; + lpUd->st.wSecond = iSecond; + TRACE("Rolled date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth, lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond); return S_OK; @@ -1250,6 +1275,8 @@ INT WINAPI DosDateTimeToVariantTime(USHORT wDosDate, USHORT wDosTime, ud.st.wMinute = DOS_MINUTE(wDosTime); ud.st.wSecond = DOS_SECOND(wDosTime); ud.st.wDayOfWeek = ud.st.wMilliseconds = 0; + if (ud.st.wHour > 23 || ud.st.wMinute > 59 || ud.st.wSecond > 59) + return FALSE; /* Invalid values in Dos*/
return VarDateFromUdate(&ud, 0, pDateOut) == S_OK; }