Piotr Caban : kernel32: Fixed TIME_CompTimeZoneID behavior on dates close to New Year's Eve.

Alexandre Julliard julliard at winehq.org
Mon Dec 10 14:00:38 CST 2012


Module: wine
Branch: master
Commit: e5a25ec5c5078d53899eb7c1b6ea08c84dc65c76
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e5a25ec5c5078d53899eb7c1b6ea08c84dc65c76

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Dec 10 11:54:23 2012 +0100

kernel32: Fixed TIME_CompTimeZoneID behavior on dates close to New Year's Eve.

---

 dlls/kernel32/tests/time.c |   23 +++++++++++++++++++++++
 dlls/kernel32/time.c       |   38 +++++++++++++++++++++++++-------------
 2 files changed, 48 insertions(+), 13 deletions(-)

diff --git a/dlls/kernel32/tests/time.c b/dlls/kernel32/tests/time.c
index e8df15b..2f71184 100644
--- a/dlls/kernel32/tests/time.c
+++ b/dlls/kernel32/tests/time.c
@@ -336,6 +336,29 @@ static void test_GetTimeZoneInformation(void)
     l_time = system_time_to_minutes(&local);
     ok(l_time - s_time == diff, "got %d, expected %d\n",
        (LONG)(l_time - s_time), diff);
+
+    /* test 23:01, 31st of December date */
+    memset(&tzinfo, 0, sizeof(tzinfo));
+    tzinfo.StandardDate.wMonth = 10;
+    tzinfo.StandardDate.wDay = 5;
+    tzinfo.StandardDate.wHour = 2;
+    tzinfo.StandardDate.wMinute = 0;
+    tzinfo.DaylightDate.wMonth = 4;
+    tzinfo.DaylightDate.wDay = 1;
+    tzinfo.DaylightDate.wHour = 2;
+    tzinfo.Bias = 0;
+    tzinfo.StandardBias = 0;
+    tzinfo.DaylightBias = -60;
+    utc.wYear = 2012;
+    utc.wMonth = 12;
+    utc.wDay = 31;
+    utc.wHour = 23;
+    utc.wMinute = 1;
+    res = pSystemTimeToTzSpecificLocalTime(&tzinfo, &utc, &local);
+    ok(res, "SystemTimeToTzSpecificLocalTime error %u\n", GetLastError());
+    ok(local.wYear==2012 && local.wMonth==12 && local.wDay==31 && local.wHour==23 && local.wMinute==1,
+            "got (%d-%d-%d %02d:%02d), expected (2012-12-31 23:01)\n",
+            local.wYear, local.wMonth, local.wDay, local.wHour, local.wMinute);
 }
 
 static void test_FileTimeToSystemTime(void)
diff --git a/dlls/kernel32/time.c b/dlls/kernel32/time.c
index 224ad70..39d3395 100644
--- a/dlls/kernel32/time.c
+++ b/dlls/kernel32/time.c
@@ -152,7 +152,7 @@ static int TIME_DayLightCompareDate( const SYSTEMTIME *date,
 static DWORD TIME_CompTimeZoneID ( const TIME_ZONE_INFORMATION *pTZinfo,
     FILETIME *lpFileTime, BOOL islocal )
 {
-    int ret;
+    int ret, year;
     BOOL beforeStandardDate, afterDaylightDate;
     DWORD retval = TIME_ZONE_ID_INVALID;
     LONGLONG llTime = 0; /* initialized to prevent gcc complaining */
@@ -177,20 +177,29 @@ static DWORD TIME_CompTimeZoneID ( const TIME_ZONE_INFORMATION *pTZinfo,
 
         if (!islocal) {
             FILETIME2LL( lpFileTime, llTime );
-            llTime -= ( pTZinfo->Bias + pTZinfo->DaylightBias )
-                * (LONGLONG)600000000;
+            llTime -= pTZinfo->Bias * (LONGLONG)600000000;
             LL2FILETIME( llTime, &ftTemp)
             lpFileTime = &ftTemp;
         }
 
         FileTimeToSystemTime(lpFileTime, &SysTime);
-        
-         /* check for daylight savings */
-        ret = TIME_DayLightCompareDate( &SysTime, &pTZinfo->StandardDate);
-        if (ret == -2)
-          return TIME_ZONE_ID_INVALID;
+        year = SysTime.wYear;
+
+        if (!islocal) {
+            llTime -= pTZinfo->DaylightBias * (LONGLONG)600000000;
+            LL2FILETIME( llTime, &ftTemp)
+            FileTimeToSystemTime(lpFileTime, &SysTime);
+        }
+
+        /* check for daylight savings */
+        if(year == SysTime.wYear) {
+            ret = TIME_DayLightCompareDate( &SysTime, &pTZinfo->StandardDate);
+            if (ret == -2)
+                return TIME_ZONE_ID_INVALID;
 
-        beforeStandardDate = ret < 0;
+            beforeStandardDate = ret < 0;
+        } else
+            beforeStandardDate = SysTime.wYear < year;
 
         if (!islocal) {
             llTime -= ( pTZinfo->StandardBias - pTZinfo->DaylightBias )
@@ -199,11 +208,14 @@ static DWORD TIME_CompTimeZoneID ( const TIME_ZONE_INFORMATION *pTZinfo,
             FileTimeToSystemTime(lpFileTime, &SysTime);
         }
 
-        ret = TIME_DayLightCompareDate( &SysTime, &pTZinfo->DaylightDate);
-        if (ret == -2)
-          return TIME_ZONE_ID_INVALID;
+        if(year == SysTime.wYear) {
+            ret = TIME_DayLightCompareDate( &SysTime, &pTZinfo->DaylightDate);
+            if (ret == -2)
+                return TIME_ZONE_ID_INVALID;
 
-        afterDaylightDate = ret >= 0;
+            afterDaylightDate = ret >= 0;
+        } else
+            afterDaylightDate = SysTime.wYear > year;
 
         retval = TIME_ZONE_ID_STANDARD;
         if( pTZinfo->DaylightDate.wMonth <  pTZinfo->StandardDate.wMonth ) {




More information about the wine-cvs mailing list