oleaut32: Rewrite RollUdate to be easier to change and to support more conversions.
This commit is contained in:
parent
c4568edd64
commit
1b51c21fb3
|
@ -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(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,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(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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
TRACE("Raw date: %d/%d/%d %d:%d:%d\n", iDay, iMonth,
|
||||
iYear, iHour, iMinute, iSecond);
|
||||
|
||||
if (iYear > 9999 || iYear < -9999)
|
||||
return E_INVALIDARG; /* Invalid value */
|
||||
/* Years < 100 are treated as 1900 + year */
|
||||
if (lpUd->st.wYear < 100)
|
||||
lpUd->st.wYear += 1900;
|
||||
if (iYear >= 0 && iYear < 100)
|
||||
iYear += 1900;
|
||||
|
||||
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)
|
||||
{
|
||||
/* Roll forward the correct number of months */
|
||||
lpUd->st.wYear++;
|
||||
lpUd->st.wMonth -= 12;
|
||||
}
|
||||
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 (lpUd->st.wYear > 9999 || lpUd->st.wHour > 23 ||
|
||||
lpUd->st.wMinute > 59 || lpUd->st.wSecond > 59)
|
||||
return E_INVALIDARG; /* Invalid values */
|
||||
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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue