oleaut32: Update the VarDateFromStr() Y2K cutoff.

Old Windows versions used 29 as the Y2K cutoff, that 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@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Francois Gouget 2021-07-16 16:07:08 +02:00 committed by Alexandre Julliard
parent 5931cf0a30
commit c83b7a0f39
2 changed files with 40 additions and 20 deletions

View File

@ -83,6 +83,8 @@ static BOOL has_locales;
#define EXPECT(x) EXPECTRES(S_OK, (x))
#define EXPECT_DBL(x) \
ok(hres == S_OK && EQ_DOUBLE(out, (x)), "expected %.16g, got %.16g; hres=0x%08x\n", (x), out, hres)
#define EXPECT_DBL2(new,old) \
ok(hres == S_OK && (EQ_DOUBLE(out, (new)) || broken(EQ_DOUBLE(out, (old)))), "expected %.16g or %.16g, got %.16g; hres=0x%08x\n", (new), (old), out, hres)
#define CONVERT(func, val) in = val; hres = func(in, &out)
#define CONVERTRANGE(func,start,end) for (i = start; i < end; i+=1) { CONVERT(func, i); EXPECT(i); };
@ -3048,21 +3050,23 @@ static void test_VarDateFromStr(void)
*/
DFS("14 1"); MKRELDATE(14,1); EXPECT_DBL(relative);
DFS("1 14"); EXPECT_DBL(relative);
/* If the numbers can't be day/month, they are assumed to be year/month */
DFS("30 2"); EXPECT_DBL(10990.0);
DFS("2 30"); EXPECT_DBL(10990.0);
/* If the numbers can't be day/month, they are assumed to be year/month.
* But see the Y2K cutoff below.
*/
DFS("30 2"); EXPECT_DBL2(47515.0, 10990.0);
DFS("2 30"); EXPECT_DBL2(47515.0, 10990.0);
DFS("32 49"); EXPECT_MISMATCH; /* Can't be any format */
DFS("0 49"); EXPECT_MISMATCH; /* Can't be any format */
/* If a month name is given the other number is the day */
DFS("Jan 2"); MKRELDATE(2,1); EXPECT_DBL(relative);
DFS("2 Jan"); EXPECT_DBL(relative);
/* Unless it can't be, in which case it becomes the year */
DFS("Jan 35"); EXPECT_DBL(12785.0);
DFS("35 Jan"); EXPECT_DBL(12785.0);
DFS("Jan-35"); EXPECT_DBL(12785.0);
DFS("35-Jan"); EXPECT_DBL(12785.0);
DFS("Jan/35"); EXPECT_DBL(12785.0);
DFS("35/Jan"); EXPECT_DBL(12785.0);
DFS("Jan 35"); EXPECT_DBL2(49310.0, 12785.0);
DFS("35 Jan"); EXPECT_DBL2(49310.0, 12785.0);
DFS("Jan-35"); EXPECT_DBL2(49310.0, 12785.0);
DFS("35-Jan"); EXPECT_DBL2(49310.0, 12785.0);
DFS("Jan/35"); EXPECT_DBL2(49310.0, 12785.0);
DFS("35/Jan"); EXPECT_DBL2(49310.0, 12785.0);
/* 3 elements */
/* 3 numbers and time separator => h:m:s */
DFS("0.1.0"); EXPECT_DBL(0.0006944444444444445);
@ -3072,12 +3076,21 @@ static void test_VarDateFromStr(void)
DFS("14 2 3"); EXPECT_DBL(41673.0);
DFS("2 14 3"); EXPECT_DBL(37666.0);
DFS("2 3 14"); EXPECT_DBL(41673.0);
DFS("32 2 3"); EXPECT_DBL(11722.0);
DFS("2 3 32"); EXPECT_DBL(11722.0);
DFS("1 2 29"); EXPECT_DBL(47120.0);
/* After 30, two digit dates are expected to be in the 1900's */
DFS("1 2 30"); EXPECT_DBL(10960.0);
DFS("1 2 31"); EXPECT_DBL(11325.0);
DFS("32 2 3"); EXPECT_DBL2(48247.0, 11722.0);
DFS("2 3 32"); EXPECT_DBL2(48247.0, 11722.0);
/* Old Windows versions use 29 as the Y2K cutoff:
* years 00-29 map to 2000-2029 while years 30-99 map to 1930-1999
*/
DFS("1 1 0"); EXPECT_DBL(36526.0);
DFS("12 31 29"); EXPECT_DBL(47483.0);
DFS("1 1 30"); EXPECT_DBL2(47484.0, 10959.0);
/* But Windows 1903+ uses 49 as the Y2K cutoff */
DFS("31 12 49"); EXPECT_DBL2(54788.0, 18263.0);
DFS("1 1 50"); EXPECT_DBL(18264.0);
DFS("12 31 99"); EXPECT_DBL(36525.0);
DFS("1 1 100"); EXPECT_DBL(-657434.0);
DFS("3 am 1 2"); MKRELDATE(2,1); relative += 0.125; EXPECT_DBL(relative);
DFS("1 2 3 am"); EXPECT_DBL(relative);

View File

@ -7554,12 +7554,19 @@ VARIANT_MakeDate_OK:
st->wDay = v1;
st->wMonth = v2;
/* FIXME: For 2 digit dates, I'm not sure if 30 is hard coded or not. It may
* be retrieved from:
* HKCU\Control Panel\International\Calendars\TwoDigitYearMax
* But Wine doesn't have/use that key as at the time of writing.
/* FIXME: For 2 digit dates old versions of Windows used 29 but
* Windows 10 1903 and greater use 49. This cutoff may also be modified by
* setting the value as a string for the relevant calendar id in the
* registry.
*
* For instance to emulate old Windows versions:
* [HKCU\Control Panel\International\Calendars\TwoDigitYearMax]
* "1"="29"
* (also 2, 9, 10, 11 and 12 for the other Gregorian calendars)
*
* But Wine doesn't have/use that key at the time of writing.
*/
st->wYear = v3 < 30 ? 2000 + v3 : v3 < 100 ? 1900 + v3 : v3;
st->wYear = v3 <= 49 ? 2000 + v3 : v3 <= 99 ? 1900 + v3 : v3;
TRACE("Returning date %d/%d/%d\n", v1, v2, st->wYear);
return S_OK;
}