RtlTimeToTimeFields fix #2 with test

Rein Klazes rklazes at xs4all.nl
Fri Oct 22 03:27:54 CDT 2004


Hi,

Similar problem as the previous one. Now with test. 

Changelog:
	dlls/ntdll	: time.c
	dlls/ntdll/tests: time.c, Makefile.in

	Correct the calculation of the year for the 31'st of December of
	2000 and every 400 years after that. Add a test used to find
	this bug.

Rein.
-- 
Rein Klazes
rklazes at xs4all.nl
-------------- next part --------------
--- wine/dlls/ntdll/time.c	2004-10-22 09:32:47.000000000 +0200
+++ mywine/dlls/ntdll/time.c	2004-10-22 09:31:05.000000000 +0200
@@ -443,6 +443,8 @@
         TimeFields->Year += DeltaYear * 400;
         Days -= DeltaYear * DAYSPERQUADRICENTENNIUM;
         DeltaYear = Days / DAYSPERNORMALCENTURY;
+        if( DeltaYear > 3) DeltaYear = 3;  /* fix 31 Dec of 2000 and every 
+                                              400 years after that */
         TimeFields->Year += DeltaYear * 100;
         Days -= DeltaYear * DAYSPERNORMALCENTURY;
         DeltaYear = Days / DAYSPERNORMALQUADRENNIUM;
--- /dev/null	2004-08-21 19:52:22.000000000 +0200
+++ mywine/dlls/ntdll/tests/time.c	2004-10-22 09:47:38.000000000 +0200
@@ -0,0 +1,91 @@
+/*
+ * Unit test suite for ntdll time functions
+ *
+ * Copyright 2004 Rein Klazes
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "ntdll_test.h"
+#define TICKSPERSEC        10000000
+#define TICKSPERMSEC       10000
+#define SECSPERDAY         86400
+
+static VOID (WINAPI *pRtlTimeToTimeFields)( const LARGE_INTEGER *liTime, PTIME_FIELDS TimeFields) ;
+
+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;
+}
+
+/* start time of the tests */
+TIME_FIELDS tftest = {1889,12,31,23,59,59,0,0};
+
+static void test_pRtlTimeToTimeFields()
+{
+    LARGE_INTEGER litime ;
+    TIME_FIELDS tfresult;
+    int i=0;
+    litime.HighPart = 0x0144017a;
+    litime.LowPart = 0xf0b0a980;
+    while( tftest.Year < 2110 ) {
+        /* test at the last second of the month */
+        pRtlTimeToTimeFields( &litime, &tfresult);
+        ok( tfresult.Year == tftest.Year && tfresult.Month == tftest.Month &&
+            tfresult.Day == tftest.Day && tfresult.Hour == tftest.Hour && 
+            tfresult.Minute == tftest.Minute && tfresult.Second == tftest.Second,
+            "#%d expected: %d-%d-%d %d:%d:%d  got:  %d-%d-%d %d:%d:%d\n", ++i,
+            tftest.Year, tftest.Month, tftest.Day,
+            tftest.Hour, tftest.Minute,tftest.Second,
+            tfresult.Year, tfresult.Month, tfresult.Day,
+            tfresult.Hour, tfresult.Minute, tfresult.Second);
+        /*  one second later is beginning of next month */
+        litime.QuadPart +=  TICKSPERSEC ;
+        pRtlTimeToTimeFields( &litime, &tfresult);
+        ok( tfresult.Year == tftest.Year + (tftest.Month ==12) &&
+            tfresult.Month == tftest.Month % 12 + 1 &&
+            tfresult.Day == 1 && tfresult.Hour == 0 && 
+            tfresult.Minute == 0 && tfresult.Second == 0,
+            "#%d expected: %d-%d-%d %d:%d:%d  got:  %d-%d-%d %d:%d:%d\n", ++i,
+            tftest.Year + (tftest.Month ==12),
+            tftest.Month % 12 + 1, 1, 0, 0, 0,
+            tfresult.Year, tfresult.Month, tfresult.Day,
+            tfresult.Hour, tfresult.Minute, tfresult.Second);
+        /* advance to the end of the month */
+        litime.QuadPart -=  TICKSPERSEC ;
+        if( tftest.Month == 12) {
+            tftest.Month = 1;
+            tftest.Year += 1;
+        } else 
+            tftest.Month += 1;
+        tftest.Day = MonthLengths[IsLeapYear(tftest.Year)][tftest.Month - 1];
+        litime.QuadPart +=  (LONGLONG) tftest.Day * TICKSPERSEC * SECSPERDAY;
+    }
+}
+
+START_TEST(time)
+{
+    HMODULE mod = GetModuleHandleA("ntdll.dll");
+    pRtlTimeToTimeFields = (void *)GetProcAddress(mod,"RtlTimeToTimeFields");
+    if (pRtlTimeToTimeFields)
+        test_pRtlTimeToTimeFields();
+}
+
--- wine/dlls/ntdll/tests/Makefile.in	2003-11-25 02:02:02.000000000 +0100
+++ mywine/dlls/ntdll/tests/Makefile.in	2004-10-21 17:43:06.000000000 +0200
@@ -14,7 +14,8 @@
 	rtl.c \
 	rtlbitmap.c \
 	rtlstr.c \
-	string.c
+	string.c \
+	time.c
 
 @MAKE_TEST_RULES@
 


More information about the wine-patches mailing list