[PATCH 1/2] A function for resolving date format and order

Vratislav Podzimek vpodzime at redhat.com
Tue Oct 7 16:32:36 UTC 2014


It's not that easy to get right order of date fields (year, month, day) and
their formats so we should better have it in a standalone function with tests.

Related: rhbz#1044233
Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
---
 pyanaconda/localization.py                  | 64 +++++++++++++++++++++++++++++
 tests/pyanaconda_tests/localization_test.py | 21 ++++++++++
 2 files changed, 85 insertions(+)

diff --git a/pyanaconda/localization.py b/pyanaconda/localization.py
index c95fa1d..efcb66f 100644
--- a/pyanaconda/localization.py
+++ b/pyanaconda/localization.py
@@ -26,6 +26,7 @@ import re
 import langtable
 import locale as locale_mod
 import glob
+from collections import namedtuple
 
 from pyanaconda import constants
 from pyanaconda.iutil import upcase_first_letter
@@ -469,3 +470,66 @@ def load_firmware_language(lang):
 
     log.debug("Using UEFI PlatformLang '%s' ('%s') as our language.", d, locales[0])
     setup_locale(locales[0], lang)
+
+_DateFieldSpec = namedtuple("DateFieldSpec", ["format", "suffix"])
+
+def resolve_date_format(year, month, day):
+    """
+    Puts the year, month and day objects in the right order according to the
+    currently set locale and provides format specification for each of the
+    fields.
+
+    :param year: any object or value representing year
+    :type year: any
+    :param month: any object or value representing month
+    :type month: any
+    :param day: any object or value representing day
+    :type day: any
+    :returns: a pair where the first field contains a tuple with the year, month
+              and day objects/values put in the right order and where the second
+              field contains a tuple with three :class:`_DateFieldSpec` objects
+              specifying formats respectively to the first (year, month, day)
+              field
+    :rtype: tuple
+    :raise ValueError: in case currently set locale has unsupported date format
+                       (likely a bug in this function)
+
+    """
+
+    # see date (1), 'O' (not '0') is a mystery, 'E' is Buddhist calendar, '(.*)'
+    # is an arbitrary suffix
+    field_spec_re = re.compile(r'([-_0OE^#]*)([yYmbBde])(.*)')
+
+    order = []
+    formats = []
+    fmt_str = locale_mod.nl_langinfo(locale_mod.D_FMT)
+
+    # see date (1)
+    fmt_str = fmt_str.replace("%F", "%Y-%m-%d")
+
+    # e.g. "%d.%m.%Y" -> ['d.', 'm.', 'Y']
+    fields = fmt_str.split("%")[1:]
+
+    for field in fields:
+        match = field_spec_re.match(field)
+        if not match:
+            # ignore fields we are not interested in (like %A for weekday name, etc.)
+            continue
+
+        prefix, item, suffix = match.groups()
+        if item in ("d", "e"):
+            # "e" is the same as "_d"
+            order.append(day)
+        elif item in ("Y", "y"):
+            # 4-digit year, 2-digit year
+            order.append(year)
+        elif item in ("m", "b", "B"):
+            # month number, short month name, long month name
+            order.append(month)
+        else:
+            raise ValueError("Unsupported date format's '%s' field '%s'" % (fmt_str, field))
+
+        # "%" + prefix + item gives a format for date/time formatting functions
+        formats.append(_DateFieldSpec("%" + prefix + item, suffix.strip()))
+
+    return (tuple(order), tuple(formats))
diff --git a/tests/pyanaconda_tests/localization_test.py b/tests/pyanaconda_tests/localization_test.py
index 00ff31d..5bf6cba 100644
--- a/tests/pyanaconda_tests/localization_test.py
+++ b/tests/pyanaconda_tests/localization_test.py
@@ -19,6 +19,8 @@
 #
 
 from pyanaconda import localization
+from pyanaconda.iutil import execReadlines
+import locale as locale_mod
 import unittest
 
 class ParsingTests(unittest.TestCase):
@@ -139,3 +141,22 @@ class LangcodeLocaleMatchingTests(unittest.TestCase):
         # no matches
         self.assertIsNone(localization.find_best_locale_match("pt_BR", ["en_BR", "en"]))
         self.assertIsNone(localization.find_best_locale_match("cs_CZ.UTF-8", ["en", "en.UTF-8"]))
+
+    def resolve_date_format_test(self):
+        """All locales' date formats should be properly resolved."""
+
+        locales = (line.strip() for line in execReadlines("locale", ["-a"]))
+        for locale in locales:
+            try:
+                locale_mod.setlocale(locale_mod.LC_ALL, locale)
+            except locale_mod.Error:
+                # cannot set locale (a bug in the locale module?)
+                continue
+
+            (order, formats) = localization.resolve_date_format(1, 2, 3)
+            if len(order) != 3:
+                self.fail("Not all date fields available for %s" % locale)
+            if len(formats) != 3:
+                self.fail("Not all date fields' formats available for %s" % locale)
+            for i in (1, 2, 3):
+                self.assertIn(i, order)
-- 
1.9.3



More information about the anaconda-patches mailing list