[glib] win32_strftime_helper: Support nominative/genitive month names



commit fa126588092334b21b05db494022e74c02ed2b0a
Author: Rafal Luzynski <digitalfreak lingonborough com>
Date:   Tue Jan 23 01:41:30 2018 +0100

    win32_strftime_helper: Support nominative/genitive month names
    
    A similar change to the commit be4f96b6502c01d2a51d60b7a669c8ef82e22a4d,
    supports %OB, %Ob, %Oh (alternative, standalone, nominative) month names
    along with the old %B, %b, %h (primary, in full date format context,
    genitive) month names.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=749206

 glib/gdate.c | 57 ++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 44 insertions(+), 13 deletions(-)
---
diff --git a/glib/gdate.c b/glib/gdate.c
index fd5e5444d..8ff224b60 100644
--- a/glib/gdate.c
+++ b/glib/gdate.c
@@ -2137,17 +2137,42 @@ static void
 append_month_name (GArray     *result,
                   LCID        lcid,
                   SYSTEMTIME *systemtime,
-                  gboolean    abbreviated)
+                  gboolean    abbreviated,
+                  gboolean    alternative)
 {
   int n;
   WORD base;
+  LPCWSTR lpFormat;
 
-  base = abbreviated ? LOCALE_SABBREVMONTHNAME1 : LOCALE_SMONTHNAME1;
-  n = GetLocaleInfoW (lcid, base + systemtime->wMonth - 1, NULL, 0);
-  g_array_set_size (result, result->len + n);
-  GetLocaleInfoW (lcid, base + systemtime->wMonth - 1,
-                 ((wchar_t *) result->data) + result->len - n, n);
-  g_array_set_size (result, result->len - 1);
+  if (alternative)
+    {
+      base = abbreviated ? LOCALE_SABBREVMONTHNAME1 : LOCALE_SMONTHNAME1;
+      n = GetLocaleInfoW (lcid, base + systemtime->wMonth - 1, NULL, 0);
+      g_array_set_size (result, result->len + n);
+      GetLocaleInfoW (lcid, base + systemtime->wMonth - 1,
+                     ((wchar_t *) result->data) + result->len - n, n);
+      g_array_set_size (result, result->len - 1);
+    }
+  else
+    {
+      /* According to MSDN, this is the correct method to obtain
+       * the form of the month name used when formatting a full
+       * date; it must be a genitive case in some languages.
+       */
+      lpFormat = abbreviated ? L"ddMMM" : L"ddMMMM";
+      n = GetDateFormatW (lcid, 0, systemtime, lpFormat, NULL, 0);
+      g_array_set_size (result, result->len + n);
+      GetDateFormatW (lcid, 0, systemtime, lpFormat,
+                     ((wchar_t *) result->data) + result->len - n, n);
+      /* We have obtained a day number as two digits and the month name.
+       * Now let's get rid of those two digits: overwrite them with the
+       * month name.
+       */
+      memmove (((wchar_t *) result->data) + result->len - n,
+              ((wchar_t *) result->data) + result->len - n + 2,
+              (n - 2) * sizeof (wchar_t));
+      g_array_set_size (result, result->len - 3);
+    }
 }
 
 static gsize
@@ -2163,7 +2188,7 @@ win32_strftime_helper (const GDate     *d,
   int n, k;
   GArray *result;
   const gchar *p;
-  gunichar c;
+  gunichar c, modifier;
   const wchar_t digits[] = L"0123456789";
   gchar *convbuf;
   glong convlen = 0;
@@ -2195,17 +2220,21 @@ win32_strftime_helper (const GDate     *d,
 
              return 0;
            }
-         
+
+         modifier = '\0';
          c = g_utf8_get_char (p);
          if (c == 'E' || c == 'O')
            {
-             /* Ignore modified conversion specifiers for now. */
+             /* "%OB", "%Ob", and "%Oh" are supported, ignore other modified
+              * conversion specifiers for now.
+              */
+             modifier = c;
              p = g_utf8_next_char (p);
              if (!*p)
                {
                  s[0] = '\0';
                  g_array_free (result, TRUE);
-                 
+
                  return 0;
                }
 
@@ -2236,10 +2265,12 @@ win32_strftime_helper (const GDate     *d,
              break;
            case 'b':
            case 'h':
-             append_month_name (result, lcid, &systemtime, TRUE);
+             append_month_name (result, lcid, &systemtime, TRUE,
+                                modifier == 'O');
              break;
            case 'B':
-             append_month_name (result, lcid, &systemtime, FALSE);
+             append_month_name (result, lcid, &systemtime, FALSE,
+                                modifier == 'O');
              break;
            case 'c':
              n = GetDateFormatW (lcid, 0, &systemtime, NULL, NULL, 0);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]