André Hentschel : oleaut32: Rewrite RollUdate to be easier to change and to support more conversions.
Alexandre Julliard
julliard at winehq.org
Tue Feb 2 10:45:29 CST 2010
Module: wine
Branch: master
Commit: 1b51c21fb30ee3fa4366d3628d343361e1696ef3
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1b51c21fb30ee3fa4366d3628d343361e1696ef3
Author: André Hentschel <nerv at 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;
}
More information about the wine-cvs
mailing list