From cfeef723d21fe93993cfb268a819ff57a591ca8c Mon Sep 17 00:00:00 2001 From: Rein Klazes Date: Fri, 29 Oct 2004 21:27:18 +0000 Subject: [PATCH] - Simplify the calculation in TIME_DaylightCompareDate; - Expand the number of applicable test cases. --- dlls/kernel/tests/time.c | 90 +++++++++++++++++++++++++++++++++------- dlls/kernel/time.c | 79 +++++++++++------------------------ 2 files changed, 100 insertions(+), 69 deletions(-) diff --git a/dlls/kernel/tests/time.c b/dlls/kernel/tests/time.c index 941a01ad54d..325d06b42e3 100644 --- a/dlls/kernel/tests/time.c +++ b/dlls/kernel/tests/time.c @@ -273,7 +273,7 @@ void test_TzSpecificLocalTimeToSystemTime() 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_TzSpecificLocalTimeToSystemTime() { 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_TzSpecificLocalTimeToSystemTime() { 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); + } } } diff --git a/dlls/kernel/time.c b/dlls/kernel/time.c index c0f291b1f2a..d663adcc024 100644 --- a/dlls/kernel/time.c +++ b/dlls/kernel/time.c @@ -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 {