[PATCH 3/3] oleaut32: Update the SystemTimeToVariantTime() Y2K cutoff.

Francois Gouget fgouget at codeweavers.com
Fri Jul 16 09:07:11 CDT 2021


Old Windows versions used 29 as the Y2K cutoff, that is is they mapped
two digit years 00-29 to 2000-2029 and years 30-99 to 1930-1999.
But starting with Windows 10 1903 the cutoff is now 49 by default.
So update Wine to match the current Windows versions and adjust the
tests to work for both.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51453
Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
This fixes a failure in oleaut32:vartest.
https://test.winehq.org/data/patterns.html#oleaut32:vartest
---
 dlls/oleaut32/tests/vartest.c | 41 +++++++++++++++++++++--------------
 dlls/oleaut32/variant.c       |  8 +++----
 2 files changed, 29 insertions(+), 20 deletions(-)

diff --git a/dlls/oleaut32/tests/vartest.c b/dlls/oleaut32/tests/vartest.c
index 8492a720855..9a9ded10406 100644
--- a/dlls/oleaut32/tests/vartest.c
+++ b/dlls/oleaut32/tests/vartest.c
@@ -2086,7 +2086,7 @@ static void test_VarDateFromUdate(void)
 }
 
 static void test_st2dt(int line, WORD d, WORD m, WORD y, WORD h, WORD mn,
-                       WORD s, WORD ms, INT r, double dt)
+                       WORD s, WORD ms, INT r, double dt, double dt2)
 {
     SYSTEMTIME st;
     double out;
@@ -2101,26 +2101,35 @@ static void test_st2dt(int line, WORD d, WORD m, WORD y, WORD h, WORD mn,
     st.wMilliseconds = ms;
     st.wDayOfWeek = 0;
     res = pSystemTimeToVariantTime(&st, &out);
-    ok_(__FILE__,line)(r == res && (!r || EQ_DOUBLE(out, dt)),
-                       "expected %d, %.16g, got %d, %.16g\n", r, dt, res, out);
+    ok_(__FILE__,line)(r == res, "expected %d, got %d\n", r, res);
+    if (r && res)
+        ok_(__FILE__,line)(EQ_DOUBLE(out, dt) || (dt2 && broken(EQ_DOUBLE(out, dt2))),
+                           "expected %.16g or %.16g, got %.16g\n", dt, dt2, out);
 }
-#define ST2DT(d,m,y,h,mn,s,ms,r,dt) test_st2dt(__LINE__,d,m,y,h,mn,s,ms,r,dt)
+#define ST2DT(d,m,y,h,mn,s,ms,r,dt,dt2) test_st2dt(__LINE__,d,m,y,h,mn,s,ms,r,dt,dt2)
 
 static void test_SystemTimeToVariantTime(void)
 {
   CHECKPTR(SystemTimeToVariantTime);
-  ST2DT(1,1,1980,0,0,0,0,TRUE,29221.0);
-  ST2DT(2,1,1980,0,0,0,0,TRUE,29222.0);
-  ST2DT(0,1,1980,0,0,0,0,TRUE,29220.0);   /* Rolls back to 31 Dec 1899 */
-  ST2DT(1,13,1980,0,0,0,0,FALSE,29587.0); /* Fails on invalid month */
-  ST2DT(32,1,1980,0,0,0,0,FALSE,0.0);     /* Fails on invalid day */
-  ST2DT(1,1,-1,0,0,0,0,FALSE,0.0);        /* Fails on invalid year */
-  ST2DT(1,1,10000,0,0,0,0,FALSE,0.0);     /* Fails on invalid year */
-  ST2DT(1,1,9999,0,0,0,0,TRUE,2958101.0); /* 9999 is last valid year */
-  ST2DT(31,12,90,0,0,0,0,TRUE,33238.0);   /* 30 <= year < 100 is 1900+year */
-  ST2DT(1,1,30,0,0,0,0,TRUE,10959.0);     /* 30 <= year < 100 is 1900+year */
-  ST2DT(1,1,29,0,0,0,0,TRUE,47119.0);     /* 0 <= year < 30 is 2000+year */
-  ST2DT(1,1,0,0,0,0,0,TRUE,36526.0);      /* 0 <= year < 30 is 2000+year */
+  ST2DT(1,1,1980,0,0,0,0,TRUE,29221.0,0.0);
+  ST2DT(2,1,1980,0,0,0,0,TRUE,29222.0,0.0);
+  ST2DT(0,1,1980,0,0,0,0,TRUE,29220.0,0.0);   /* Rolls back to 31 Dec 1899 */
+  ST2DT(1,13,1980,0,0,0,0,FALSE,0.0,0.0);     /* Fails on invalid month */
+  ST2DT(32,1,1980,0,0,0,0,FALSE,0.0,0.0);     /* Fails on invalid day */
+  ST2DT(1,1,-1,0,0,0,0,FALSE,0.0,0.0);        /* Fails on invalid year */
+  ST2DT(1,1,10000,0,0,0,0,FALSE,0.0,0.0);     /* Fails on invalid year */
+  ST2DT(1,1,9999,0,0,0,0,TRUE,2958101.0,0.0); /* 9999 is last valid year */
+
+  /* Old Windows versions use 29 as the Y2K cutoff:
+   * years 00-29 map to 2000-2029 while years 30-99 map to 1930-1999
+   */
+  ST2DT(1,1,0,0,0,0,0,TRUE,36526.0,0.0);
+  ST2DT(1,1,29,0,0,0,0,TRUE,47119.0,0.0);
+  ST2DT(1,1,30,0,0,0,0,TRUE,47484.0,10959.0);
+  /* But Windows 1903+ uses 49 as the Y2K cutoff */
+  ST2DT(1,1,49,0,0,0,0,TRUE,54424.0,17899.0);
+  ST2DT(1,1,50,0,0,0,0,TRUE,18264.0,0.0);
+  ST2DT(31,12,99,0,0,0,0,TRUE,36525.0,0.0);
 }
 
 static void test_dt2st(int line, double dt, INT r, WORD d, WORD m, WORD y,
diff --git a/dlls/oleaut32/variant.c b/dlls/oleaut32/variant.c
index 129e13da17d..b3a568c355c 100644
--- a/dlls/oleaut32/variant.c
+++ b/dlls/oleaut32/variant.c
@@ -1124,11 +1124,11 @@ static HRESULT VARIANT_RollUdate(UDATE *lpUd)
 
   if (iYear > 9999 || iYear < -9999)
     return E_INVALIDARG; /* Invalid value */
-  /* Year 0 to 29 are treated as 2000 + year */
-  if (iYear >= 0 && iYear < 30)
+  /* Years 0 to 49 are treated as 2000 + year, see also VARIANT_MakeDate() */
+  if (0 <= iYear && iYear <= 49)
     iYear += 2000;
-  /* Remaining years < 100 are treated as 1900 + year */
-  else if (iYear >= 30 && iYear < 100)
+  /* Remaining years 50 to 99 are treated as 1900 + year */
+  else if (50 <= iYear && iYear <= 99)
     iYear += 1900;
 
   iMinute += iSecond / 60;
-- 
2.20.1



More information about the wine-devel mailing list