Simplify TIME_DaylightCompareDate
Rein Klazes
rklazes at xs4all.nl
Fri Oct 29 08:22:00 CDT 2004
Hi,
Changelog:
dlls/kernel : time.c
dlls/kernel/tests : time.c
- Simplify the calculation in TIME_DaylightCompareDate;
- Expand the number of applicable test cases.
Rein.
--
Rein Klazes
rklazes at xs4all.nl
-------------- next part --------------
--- wine/dlls/kernel/time.c 2004-10-28 08:36:06.000000000 +0200
+++ mywine/dlls/kernel/time.c 2004-10-29 11:45:59.000000000 +0200
@@ -59,6 +59,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(time);
#define FILETIME2LL( pft, ll) \
ll = (((LONGLONG)((pft)->dwHighDateTime))<<32) + (pft)-> dwLowDateTime ;
+
+static const int MonthLengths[2][12] =
+{
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+ { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+
+static inline int IsLeapYear(int Year)
+{
+ return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 1 : 0;
+}
+
/***********************************************************************
* TIME_DayLightCompareDate
*
@@ -86,61 +98,18 @@ static int TIME_DayLightCompareDate(
if (compareDate->wDayOfWeek <= 6)
{
- SYSTEMTIME tmp;
- FILETIME tmp_ft;
-
- /* compareDate->wDay is interpreted as number of the week in the month
- * 5 means: the last week in the month */
- int weekofmonth = compareDate->wDay;
-
- /* calculate day of week for the first day in the month */
- memcpy(&tmp, date, sizeof(SYSTEMTIME));
- tmp.wDay = 1;
- tmp.wDayOfWeek = -1;
-
- if (weekofmonth == 5)
- {
- /* Go to the beginning of the next month. */
- if (++tmp.wMonth > 12)
- {
- tmp.wMonth = 1;
- ++tmp.wYear;
- }
- }
-
- if (!SystemTimeToFileTime(&tmp, &tmp_ft))
- return -2;
-
- if (weekofmonth == 5)
- {
- LONGLONG t;
- FILETIME2LL( &tmp_ft, t)
- /* subtract one day */
- t -= (LONGLONG) 24*60*60*10000000;
- LL2FILETIME( t, &tmp_ft);
- }
-
- if (!FileTimeToSystemTime(&tmp_ft, &tmp))
- return -2;
-
- if (weekofmonth == 5)
- {
- /* calculate the last matching day of the week in this month */
- int dif = tmp.wDayOfWeek - compareDate->wDayOfWeek;
- if (dif < 0)
- dif += 7;
-
- limit_day = tmp.wDay - dif;
- }
- else
- {
- /* calculate the matching day of the week in the given week */
- int dif = compareDate->wDayOfWeek - tmp.wDayOfWeek;
- if (dif < 0)
- dif += 7;
-
- limit_day = tmp.wDay + 7*(weekofmonth-1) + dif;
- }
+ WORD First;
+ /* compareDate->wDay is interpreted as number of the week in the month
+ * 5 means: the last week in the month */
+ int weekofmonth = compareDate->wDay;
+ /* calculate the day of the first DayOfWeek in the month */
+ First = ( 6 + compareDate->wDayOfWeek - date->wDayOfWeek + date->wDay
+ ) % 7 + 1;
+ limit_day = First + 7 * (weekofmonth - 1);
+ /* check needed for the 5th weekday of the month */
+ if(limit_day > MonthLengths[date->wMonth==2 && IsLeapYear(date->wYear)]
+ [date->wMonth - 1])
+ limit_day -= 7;
}
else
{
--- wine/dlls/kernel/tests/time.c 2004-10-28 08:36:08.000000000 +0200
+++ mywine/dlls/kernel/tests/time.c 2004-10-29 15:09:43.000000000 +0200
@@ -273,7 +273,7 @@ void test_TzSpecificLocalTimeToSystemTim
fnSystemTimeToTzSpecificLocalTime pSystemTimeToTzSpecificLocalTime = NULL;
TIME_ZONE_INFORMATION tzE, tzW, tzS;
SYSTEMTIME result;
- int i;
+ int i, j, year;
pTzSpecificLocalTimeToSystemTime = (fnTzSpecificLocalTimeToSystemTime) GetProcAddress( hKernel, "TzSpecificLocalTimeToSystemTime");
if(pTzSpecificLocalTimeToSystemTime)
pSystemTimeToTzSpecificLocalTime = (fnTzSpecificLocalTimeToSystemTime) GetProcAddress( hKernel, "SystemTimeToTzSpecificLocalTime");
@@ -341,14 +341,45 @@ void test_TzSpecificLocalTimeToSystemTim
{ 17, &tzS, {2004,10,-1,24,1,59,59,999}, 5},
{ 18, &tzS, {2004,10,-1,24,2,0,0,0}, 5},
{0}
- };
- for (i=0; cases[i].nr; i++) {
- pTzSpecificLocalTimeToSystemTime( cases[i].ptz, &(cases[i].slt), &result);
- ok( result.wHour == cases[i].ehour,
- "Test TzSpecificLocalTimeToSystemTime #%d. wrong system time. Hour is %d expected %d\n",
- cases[i].nr, result.wHour, cases[i].ehour);
+ };
+ /* days of transitions to put into the cases array */
+ int yeardays[][6]=
+ {
+ {28,31,4,24,4,24} /* 1999 */
+ , {26,29,2,22,2,22} /* 2000 */
+ , {25,28,1,28,1,28} /* 2001 */
+ , {31,27,7,27,7,27} /* 2002 */
+ , {30,26,6,26,6,26} /* 2003 */
+ , {28,31,4,24,4,24} /* 2004 */
+ , {27,30,3,23,3,23} /* 2005 */
+ , {26,29,2,22,2,22} /* 2006 */
+ , {25,28,1,28,1,28} /* 2007 */
+ , {30,26,6,26,6,26} /* 2008 */
+ , {29,25,5,25,5,25} /* 2009 */
+ , {28,31,4,24,4,24} /* 2010 */
+ , {27,30,3,23,3,23} /* 2011 */
+ , {25,28,1,28,1,28} /* 2012 */
+ , {31,27,7,27,7,27} /* 2013 */
+ , {30,26,6,26,6,26} /* 2014 */
+ , {29,25,5,25,5,25} /* 2015 */
+ , {27,30,3,23,3,23} /* 2016 */
+ , {26,29,2,22,2,22} /* 2017 */
+ , {25,28,1,28,1,28} /* 2018 */
+ , {31,27,7,27,7,27} /* 2019 */
+ ,{0}
+ };
+ for( j=0 , year = 1999; yeardays[j][0] ; j++, year++) {
+ for (i=0; cases[i].nr; i++) {
+ if(i) cases[i].nr += 18;
+ cases[i].slt.wYear = year;
+ cases[i].slt.wDay = yeardays[j][i/3];
+ pTzSpecificLocalTimeToSystemTime( cases[i].ptz, &(cases[i].slt), &result);
+ ok( result.wHour == cases[i].ehour,
+ "Test TzSpecificLocalTimeToSystemTime #%d. Got %4d-%02d-%02d %02d:%02d. Expect hour = %02d\n",
+ cases[i].nr, result.wYear, result.wMonth, result.wDay,
+ result.wHour, result.wMinute, cases[i].ehour);
+ }
}
-
}
/* SystemTimeToTzSpecificLocalTime */
{ TZLT2ST_case cases[] = {
@@ -376,12 +407,43 @@ void test_TzSpecificLocalTimeToSystemTim
{ 18, &tzS, {2004,10,-1,24,6,0,0,0}, 3},
{0}
- };
- for (i=0; cases[i].nr; i++) {
- pSystemTimeToTzSpecificLocalTime( cases[i].ptz, &(cases[i].slt), &result);
- ok( result.wHour == cases[i].ehour,
- "Test SystemTimeToTzSpecificLocalTime #%d. wrong system time. Hour is %d expected %d\n",
- cases[i].nr, result.wHour, cases[i].ehour);
+ };
+ /* days of transitions to put into the cases array */
+ int yeardays[][6]=
+ {
+ {27,30,4,24,4,24} /* 1999 */
+ , {25,28,2,22,2,22} /* 2000 */
+ , {24,27,1,28,1,28} /* 2001 */
+ , {30,26,7,27,7,27} /* 2002 */
+ , {29,25,6,26,6,26} /* 2003 */
+ , {27,30,4,24,4,24} /* 2004 */
+ , {26,29,3,23,3,23} /* 2005 */
+ , {25,28,2,22,2,22} /* 2006 */
+ , {24,27,1,28,1,28} /* 2007 */
+ , {29,25,6,26,6,26} /* 2008 */
+ , {28,24,5,25,5,25} /* 2009 */
+ , {27,30,4,24,4,24} /* 2010 */
+ , {26,29,3,23,3,23} /* 2011 */
+ , {24,27,1,28,1,28} /* 2012 */
+ , {30,26,7,27,7,27} /* 2013 */
+ , {29,25,6,26,6,26} /* 2014 */
+ , {28,24,5,25,5,25} /* 2015 */
+ , {26,29,3,23,3,23} /* 2016 */
+ , {25,28,2,22,2,22} /* 2017 */
+ , {24,27,1,28,1,28} /* 2018 */
+ , {30,26,7,27,7,27} /* 2019 */
+ };
+ for( j=0 , year = 1999; yeardays[j][0] ; j++, year++) {
+ for (i=0; cases[i].nr; i++) {
+ if(i) cases[i].nr += 18;
+ cases[i].slt.wYear = year;
+ cases[i].slt.wDay = yeardays[j][i/3];
+ pSystemTimeToTzSpecificLocalTime( cases[i].ptz, &(cases[i].slt), &result);
+ ok( result.wHour == cases[i].ehour,
+ "Test SystemTimeToTzSpecificLocalTime #%d. Got %4d-%02d-%02d %02d:%02d. Expect hour = %02d\n",
+ cases[i].nr, result.wYear, result.wMonth, result.wDay,
+ result.wHour, result.wMinute, cases[i].ehour);
+ }
}
}
More information about the wine-patches
mailing list