I'm translating GnuCash to Japanese. Some date/time shown in the status bar appears to use 'C' instead of the user locale (e.g. LANG=ja_JP.UTF-8 in my env). https://imagebin.ca/v/4QDPHJMy620D > #: gnucash/gnome-utils/gnc-main-window.c:1678 I expect %a to become '月' instead of 'Mon', and %p to '午前' instead of 'AM'. https://imagebin.ca/v/4QDULP289QOu > #: gnucash/gnome-utils/gnc-tree-util-split-reg.c:436 > #: gnucash/register/ledger-core/gncEntryLedgerModel.c:576 > #: gnucash/register/ledger-core/split-register-model.c:980 likewise; %A to '月曜日' instead of 'Monday'. Here is part of my updating ja.po: > #: gnucash/gnome-utils/gnc-main-window.c:1678 > msgid "Last modified on %a, %b %d, %Y at %I:%M %p" > msgstr "最終更新: %Y年%m月%d日 %a %p %I:%M" > #: gnucash/register/ledger-core/split-register-model.c:980 > msgid "%A %d %B %Y" > msgstr "%Y年%m月%d日 %A"
Starting at https://wiki.gnucash.org/logs/2018/12/16.html#T10:29:53 we talked the first time about it.
--- gnucash-3.3.orig/libgnucash/engine/gnc-datetime.cpp +++ gnucash-3.3/libgnucash/engine/gnc-datetime.cpp @@ -395,7 +395,7 @@ GncDateTimeImpl::format(const char* form std::stringstream ss; //The stream destructor frees the facet, so it must be heap-allocated. auto output_facet(new Facet(normalize_format(format).c_str())); - ss.imbue(std::locale(std::locale(), output_facet)); + ss.imbue(std::locale(std::locale(""), output_facet)); ss << m_time; return ss.str(); } @@ -407,7 +407,7 @@ GncDateTimeImpl::format_zulu(const char* std::stringstream ss; //The stream destructor frees the facet, so it must be heap-allocated. auto output_facet(new Facet(normalize_format(format).c_str())); - ss.imbue(std::locale(std::locale(), output_facet)); + ss.imbue(std::locale(std::locale(""), output_facet)); ss << m_time.utc_time(); return ss.str(); } @@ -466,7 +466,7 @@ GncDateImpl::format(const char* format) std::stringstream ss; //The stream destructor frees the facet, so it must be heap-allocated. auto output_facet(new Facet(normalize_format(format).c_str())); - ss.imbue(std::locale(std::locale(), output_facet)); + ss.imbue(std::locale(std::locale(""), output_facet)); ss << m_greg; return ss.str(); } This apparently fixes this problem, but this code is costly because it looks for the user locale each time when it formats datetime.
In commit 7f1a711 I applied your suggestion. I added comments for a cleanup of our boost::locale handling in the future. Thank you very much!
While the commit does fix the translation issue, we now have a broken test suite when run in any locale other than C :( My system defaults to nl_BE, and I get this error while running "make check": /qof/gnc-date/gnc ctime: ** ERROR:/home/janssege/Development/gnucash/maint/libgnucash/engine/test/test-gnc-date.c:356:test_gnc_ctime: assertion failed (datestr == check_str): ("vr dec 19 00:51:48 1969" == "Fri Dec 19 00:51:48 1969") <end of output> As you can see "Fri Dec" is translated as "vr dec" in Dutch. This is the new behaviour we expect so this test needs updating. In fact there are now two things to test: 1. test whether to code generates the proper date string in the C locale 2. test whether the code generated the proper date string in other locales. For the first test, the locale in the test should be set to "C" before running the test. For the second test we should test a few other locales. We do something similar in other parts of the test suite. I believe we specifically install en and fr locales in our test environment on travis to run some tests under fr_FR and en_GB locales.
Actually it just needed the comparison string to be localized too. The ctime test compares against the result of strftime(), but setlocale(LC_ALL, "") wasn't being called to localize strftime's output but is called in gnc_get_locale() that sets the C++ locale. Since in this case localization is applied inside boost::date_time I don't think there's much point in testing it in our unit tests beyond ensuring that the test passes for the builder's locale. The locale-specific tests in test-gnc-date.c test the locale-format retrieving code in qof_date_format_get_string.