monthcal.c patch.txt

s.p. darseq at gmail.com
Fri Aug 14 11:54:05 CDT 2015


Countries use different rules for determining week numbers. For the classic
month calendar however, windows seems to ignore the first week of the year
registry setting. The attached file 'patch.txt' addresses this quirk by
simply implementing the rules of ISO8601. Although this patch works and has
been tested, it is not intended as a complete fix. For that it probably
needs some more investigation. Usage:


cd wine/dlls/comctl32
patch monthcal.c < patch.txt

Greets, sbmpost
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20150814/b9d837b6/attachment.html>
-------------- next part --------------
--- monthcal.org.c	2015-08-14 17:50:07.000000000 +0200
+++ monthcal.c	2015-08-14 18:04:16.000000000 +0200
@@ -899,10 +899,11 @@
 
 static void MONTHCAL_PaintWeeknumbers(const MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps, INT calIdx)
 {
-  const SYSTEMTIME *date = &infoPtr->calendars[calIdx].month;
+  // week numbers patch by sbmpost
+  // week1 day mapping: su, mo, tu, we, th, fr, sa
+  static const INT week1[] = { -1,0,1,2,3,-3,-2 };
   static const WCHAR fmt_weekW[] = { '%','d',0 };
-  INT mindays, weeknum, weeknum1, startofprescal;
-  INT i, prev_month;
+  INT i, weeknum, jan1;
   SYSTEMTIME st;
   WCHAR buf[80];
   HPEN old_pen;
@@ -911,11 +912,25 @@
   if (!(infoPtr->dwStyle & MCS_WEEKNUMBERS)) return;
 
   MONTHCAL_GetMinDate(infoPtr, &st);
-  startofprescal = st.wDay;
-  st = *date;
-
-  prev_month = date->wMonth - 1;
-  if(prev_month == 0) prev_month = 12;
+  weeknum = st.wDay;
+  for (i = 0; i < st.wMonth - 1; i++) {
+      weeknum += MONTHCAL_MonthLength(i+1, st.wYear);
+  }
+
+  st.wMonth = st.wDay = 1;
+  jan1 = MONTHCAL_CalculateDayOfWeek(&st, FALSE);
+  weeknum = (weeknum+week1[jan1]+6)/7;
+
+  if (weeknum == 0) {
+    weeknum = 52;
+    st.wYear--;
+    jan1 = MONTHCAL_CalculateDayOfWeek(&st, FALSE);
+    weeknum = weeknum + !!(jan1 == 4 || (jan1 == 3 &&
+      (st.wYear%400 == 0 || (st.wYear%4 == 0 && st.wYear%100 != 0))));
+  } else if (weeknum == 53 && !(jan1 == 4 || (jan1 == 3 &&
+      (st.wYear%400 == 0 || (st.wYear%4 == 0 && st.wYear%100 != 0))))) {
+    weeknum = 1;
+  }
 
   /*
      Rules what week to call the first week of a new year:
@@ -925,7 +940,7 @@
      First week of year must contain 4 days of the new year
      LOCALE_IFIRSTWEEKOFYEAR == 1  (what countries?)
      The first week of the year must contain only days of the new year
-  */
+
   GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IFIRSTWEEKOFYEAR, buf, countof(buf));
   weeknum = atoiW(buf);
   switch (weeknum)
@@ -940,39 +955,7 @@
         WARN("Unknown LOCALE_IFIRSTWEEKOFYEAR value %d, defaulting to 0\n", weeknum);
 	mindays = 0;
   }
-
-  if (date->wMonth == 1)
-  {
-    /* calculate all those exceptions for January */
-    st.wDay = st.wMonth = 1;
-    weeknum1 = MONTHCAL_CalculateDayOfWeek(&st, FALSE);
-    if ((infoPtr->firstDay - weeknum1) % 7 > mindays)
-	weeknum = 1;
-    else
-    {
-	weeknum = 0;
-	for(i = 0; i < 11; i++)
-	   weeknum += MONTHCAL_MonthLength(i+1, date->wYear - 1);
-
-	weeknum  += startofprescal + 7;
-	weeknum  /= 7;
-	st.wYear -= 1;
-	weeknum1  = MONTHCAL_CalculateDayOfWeek(&st, FALSE);
-	if ((infoPtr->firstDay - weeknum1) % 7 > mindays) weeknum++;
-    }
-  }
-  else
-  {
-    weeknum = 0;
-    for(i = 0; i < prev_month - 1; i++)
-	weeknum += MONTHCAL_MonthLength(i+1, date->wYear);
-
-    weeknum += startofprescal + 7;
-    weeknum /= 7;
-    st.wDay = st.wMonth = 1;
-    weeknum1 = MONTHCAL_CalculateDayOfWeek(&st, FALSE);
-    if ((infoPtr->firstDay - weeknum1) % 7 > mindays) weeknum++;
-  }
+  */
 
   r = infoPtr->calendars[calIdx].weeknums;
 


More information about the wine-patches mailing list