Correct VarBstrFromDate for dates between DATE_MIN and 1601

Bill Medland billmedland at shaw.ca
Fri May 4 13:22:03 CDT 2007


Bill Medland (billmedland at shaw.ca)
Correct VarBstrFromDate for dates between DATE_MIN and 1601

Index: wine/include/winnls.h
===================================================================
RCS file: /home/wine/wine/include/winnls.h,v
retrieving revision 1.51
diff -u -r1.51 winnls.h
--- wine/include/winnls.h	15 Mar 2007 13:20:31 -0000	1.51
+++ wine/include/winnls.h	4 May 2007 18:13:53 -0000
@@ -356,6 +356,7 @@
 #define DATE_YEARMONTH          0x08  /* Year/month format */
 #define DATE_LTRREADING         0x10  /* Add LTR reading marks */
 #define DATE_RTLREADING         0x20  /* Add RTL reading marks */
+#define WINE_DATE_ALLDATES      0x8000 /* Allow all SYSTEMTIME dates */
 
 #define TIME_FORCE24HOURFORMAT  0x08  /* Always use 24 hour clock */
 #define TIME_NOTIMEMARKER       0x04  /* show no AM/PM */
Index: wine/dlls/kernel32/lcformat.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel32/lcformat.c,v
retrieving revision 1.5
diff -u -r1.5 lcformat.c
--- wine/dlls/kernel32/lcformat.c	18 Jan 2007 12:47:12 -0000	1.5
+++ wine/dlls/kernel32/lcformat.c	4 May 2007 18:14:14 -0000
@@ -342,6 +342,9 @@
  * FIXME
  * DATE_USE_ALT_CALENDAR           - Requires GetCalendarInfo to work first.
  * DATE_LTRREADING/DATE_RTLREADING - Not yet implemented.
+ * WINE_DATE_ALLDATES              - Allow all dates storable in a SYSTEMTIME
+ *  (but if the date is before 1 January 1601 then the Day of Week will not be
+ *  adjusted)
  */
 static INT NLS_GetDateTimeFormatW(LCID lcid, DWORD dwFlags,
                                   const SYSTEMTIME* lpTime, LPCWSTR lpFormat,
@@ -418,7 +421,7 @@
   }
   else
   {
-    if (dwFlags & DATE_DATEVARSONLY)
+    if ((dwFlags & DATE_DATEVARSONLY) && (lpTime->wYear >= 1601 || !(dwFlags & WINE_DATE_ALLDATES)))
     {
       FILETIME ftTmp;
 
@@ -428,7 +431,7 @@
       st.wMonth = lpTime->wMonth;
       st.wDay = lpTime->wDay;
 
-      if (st.wDay > 31 || st.wMonth > 12 || !SystemTimeToFileTime(&st, &ftTmp))
+      if (!SystemTimeToFileTime(&st, &ftTmp))
         goto NLS_GetDateTimeFormatW_InvalidParameter;
 
       FileTimeToSystemTime(&ftTmp, &st);
@@ -521,7 +524,14 @@
       case 'y':
         if (count >= 4)
         {
-          count = 4;
+          /* In the special case of WINE_DATE_ALLDATES the year could be less
+           * than 1000 (especially could be 100) and VarBstrFromDate will need
+           * to generate only 3 year digits.  VarBstrFromDate will not pass
+           * less than 100 so we do not need 2 and 1.
+           * If WINE_DATE_ALLDATES is not set then the year will be at least
+           * 1601.
+           */
+          count = (lpTime->wYear < 1000) ? 3 : 4;
           dwVal = lpTime->wYear;
         }
         else
Index: wine/dlls/kernel32/tests/locale.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel32/tests/locale.c,v
retrieving revision 1.12
diff -u -r1.12 locale.c
--- wine/dlls/kernel32/tests/locale.c	4 May 2007 12:13:28 -0000	1.12
+++ wine/dlls/kernel32/tests/locale.c	4 May 2007 18:14:25 -0000
@@ -452,6 +452,21 @@
   SetLastError(0xdeadbeef);
   ret = GetDateFormatW (lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
   EXPECT_INVALID;
+
+  /* The minimum date in a Variant */
+  curtime.wYear = 100;
+  curtime.wMonth = 1;
+  curtime.wDay = 1;
+  curtime.wDayOfWeek = 0;
+  curtime.wHour = 0;
+  curtime.wMinute = 0;
+  curtime.wSecond = 0;
+  curtime.wMilliseconds = 0;
+  STRINGSW("","1/1/100");
+  SetLastError(0xdeadbeef);
+  ret = GetDateFormatW (lcid, DATE_SHORTDATE|WINE_DATE_ALLDATES, &curtime, 0, buffer, COUNTOF(buffer));
+  EXPECT_VALID; EXPECT_LENW; EXPECT_EQW;
+
 }
 
 
Index: wine/dlls/oleaut32/vartype.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/vartype.c,v
retrieving revision 1.37
diff -u -r1.37 vartype.c
--- wine/dlls/oleaut32/vartype.c	13 Apr 2007 11:51:38 -0000	1.37
+++ wine/dlls/oleaut32/vartype.c	4 May 2007 18:14:51 -0000
@@ -6584,8 +6584,8 @@
   if (dwFlags & VAR_TIMEVALUEONLY)
     date[0] = '\0';
   else
-    if (!GetDateFormatW(lcid, dwFormatFlags|DATE_SHORTDATE, &st, NULL, date,
-                        sizeof(date)/sizeof(WCHAR)))
+    if (!GetDateFormatW(lcid, dwFormatFlags|DATE_SHORTDATE|WINE_DATE_ALLDATES,
+                        &st, NULL, date, sizeof(date)/sizeof(WCHAR)))
       return E_INVALIDARG;
 
   if (!(dwFlags & VAR_DATEVALUEONLY))
Index: wine/dlls/oleaut32/tests/vartype.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/tests/vartype.c,v
retrieving revision 1.49
diff -u -r1.49 vartype.c
--- wine/dlls/oleaut32/tests/vartype.c	4 May 2007 12:13:29 -0000	1.49
+++ wine/dlls/oleaut32/tests/vartype.c	4 May 2007 18:14:58 -0000
@@ -4784,7 +4784,7 @@
   BSTR_DATE(365.25, "12/30/1900 6:00:00 AM");
   BSTR_DATE(1461.0, "12/31/1903");
   BSTR_DATE(1461.5, "12/31/1903 12:00:00 PM");
-  todo_wine { BSTR_DATE(-657434.0, "1/1/100"); }
+  BSTR_DATE(-657434.0, "1/1/100");
   BSTR_DATE(2958465.0, "12/31/9999");
 }
 





More information about the wine-patches mailing list