[california] Date/time localization: Closes bgo#726044



commit 32d86cf5a6c45439c218cadb1ca42e38744b4493
Author: Jim Nelson <jim yorba org>
Date:   Mon Mar 10 18:30:39 2014 -0700

    Date/time localization: Closes bgo#726044
    
    In addition to the translation comments, also swap out LC_MESSAGES
    with LC_TIME to pull the time/date format for that locale, to allow
    users to specify a time locale different from their language.

 src/calendar/calendar-wall-time.vala |   13 +++--
 src/calendar/calendar.vala           |   96 +++++++++++++++++++++++++++++++---
 2 files changed, 95 insertions(+), 14 deletions(-)
---
diff --git a/src/calendar/calendar-wall-time.vala b/src/calendar/calendar-wall-time.vala
index d0af39a..e9b23ab 100644
--- a/src/calendar/calendar-wall-time.vala
+++ b/src/calendar/calendar-wall-time.vala
@@ -263,10 +263,8 @@ public class WallTime : BaseObject, Gee.Comparable<WallTime>, Gee.Hashable<WallT
         bool meridiem_post_only = (flags & PrettyFlag.MERIDIEM_POST_ONLY) != 0;
         bool brief_meridiem = (flags & PrettyFlag.BRIEF_MERIDIEM) != 0;
         
-        // TODO: localize all this
-        
-        unowned string pm = brief_meridiem ? "p" : "pm";
-        unowned string am = brief_meridiem ? "a" : "am";
+        unowned string pm = brief_meridiem ? FMT_BRIEF_PM : FMT_PM;
+        unowned string am = brief_meridiem ? FMT_BRIEF_AM : FMT_AM;
         
         unowned string meridiem;
         if (meridiem_post_only)
@@ -274,13 +272,16 @@ public class WallTime : BaseObject, Gee.Comparable<WallTime>, Gee.Hashable<WallT
         else
             meridiem = is_pm? pm : am;
         
+        // Not marked for translation on thw assumption that a 12-hour hour followed by the meridiem
+        // isn't something that varies between locales, on the assumption that the user has
+        // specified 12-hour time to begin with
         if (optional_min && minute == 0)
             return "%d%s".printf(12hour, meridiem);
         
         if (!include_sec)
-            return "%d:%02d%s".printf(12hour, minute, meridiem);
+            return FMT_12HOUR_MIN_MERIDIEM.printf(12hour, minute, meridiem);
         
-        return "%d:%02d:%02d%s".printf(12hour, minute, second, meridiem);
+        return FMT_12HOUR_MIN_SEC_MERIDIEM.printf(12hour, minute, second, meridiem);
     }
     
     public int compare_to(WallTime other) {
diff --git a/src/calendar/calendar.vala b/src/calendar/calendar.vala
index 6ab23da..193c2d7 100644
--- a/src/calendar/calendar.vala
+++ b/src/calendar/calendar.vala
@@ -30,26 +30,106 @@ private static unowned string FMT_PRETTY_DATE;
 private static unowned string FMT_PRETTY_DATE_NO_YEAR;
 private static unowned string FMT_PRETTY_DATE_ABBREV;
 private static unowned string FMT_PRETTY_DATE_ABBREV_NO_YEAR;
+private static unowned string FMT_AM;
+private static unowned string FMT_BRIEF_AM;
+private static unowned string FMT_PM;
+private static unowned string FMT_BRIEF_PM;
+private static unowned string FMT_12HOUR_MIN_MERIDIEM;
+private static unowned string FMT_12HOUR_MIN_SEC_MERIDIEM;
 
 public void init() throws Error {
     if (!California.Unit.do_init(ref init_count))
         return;
     
-    // TODO: Properly fetch these from gettext() so the user's locale is respected (not just their
-    // language)
-    // TODO: Translator comments explaining these are strftime formatted strings
+    // Ripped from Shotwell proposed patch for localizing time (http://redmine.yorba.org/issues/2462)
+    // courtesy Marcel Stimberg.  Another example may be found here:
+    // 
http://bazaar.launchpad.net/~indicator-applet-developers/indicator-datetime/trunk.12.10/view/head:/src/utils.c
+    
+    // Because setlocale() is a process-wide setting, need to cache strings at startup, otherwise
+    // risk problems with threading
+    
+    string? messages_locale = Intl.setlocale(LocaleCategory.MESSAGES, null);
+    string? time_locale = Intl.setlocale(LocaleCategory.TIME, null);
+    
+    // LANGUAGE must be unset before changing locales, as it trumps all the LC_* variables
+    string? language_env = Environment.get_variable("LANGUAGE");
+    if (language_env != null)
+        Environment.unset_variable("LANGUAGE");
+    
+    // Swap LC_TIME's setting into LC_MESSAGE's.  This allows performing lookups of time-based values
+    // from a different translation file, useful in mixed-locale settings
+    if (time_locale != null)
+        Intl.setlocale(LocaleCategory.MESSAGES, time_locale);
+    
+    // These are not marked for translation because they involve no ordering of format specifiers
+    // and strftime handles translating them to the locale
+    FMT_MONTH_FULL = "%B";
+    FMT_MONTH_ABBREV = "%b";
+    FMT_DAY_OF_WEEK_FULL = "%A";
+    FMT_DAY_OF_WEEK_ABBREV = "%a";
+    FMT_FULL_DATE = "%x";
+    
+    /// The month and year according to locale preferences, i.e. "March 2014"
+    /// See http://www.cplusplus.com/reference/ctime/strftime/ for format reference
     FMT_MONTH_YEAR_FULL = _("%B %Y");
+    
+    /// The abbreviated month and year according to locale preferences, i.e. "Mar 2014"
+    /// See http://www.cplusplus.com/reference/ctime/strftime/ for format reference
     FMT_MONTH_YEAR_ABBREV = _("%b %Y");
-    FMT_MONTH_FULL = _("%B");
-    FMT_MONTH_ABBREV = _("%b");
-    FMT_DAY_OF_WEEK_FULL = _("%A");
-    FMT_DAY_OF_WEEK_ABBREV = _("%a");
-    FMT_FULL_DATE = _("%x");
+    
+    /// A "pretty" date according to locale preferences, i.e. "Monday, March 10, 2014"
+    /// See http://www.cplusplus.com/reference/ctime/strftime/ for format reference
     FMT_PRETTY_DATE = _("%A, %B %e, %Y");
+    
+    /// A "pretty" date with no year according to locale preferences, i.e. "Monday, March 10"
+    /// See http://www.cplusplus.com/reference/ctime/strftime/ for format reference
     FMT_PRETTY_DATE_NO_YEAR = _("%A, %B %e");
+    
+    /// A "pretty" date abbreviated according to locale preferences, i.e. "Mon, Mar 10, 2014"
+    /// See http://www.cplusplus.com/reference/ctime/strftime/ for format reference
     FMT_PRETTY_DATE_ABBREV = _("%a, %b %e, %Y");
+    
+    /// A "pretty" date abbreviated and no year according to locale preferences, i.e.
+    /// "Mon, Mar 10"
+    /// See http://www.cplusplus.com/reference/ctime/strftime/ for format reference
     FMT_PRETTY_DATE_ABBREV_NO_YEAR = _("%a, %b %e");
     
+    /// Ante meridiem
+    /// (Please translate even if 24-hour clock used in your locale; this allows for GNOME time
+    /// format user settings to be honored)
+    FMT_AM = _("am");
+    
+    /// Brief ante meridiem, i.e. "am" -> "a"
+    /// (Please translate even if 24-hour clock used in your locale; this allows for GNOME time
+    /// format user settings to be honored)
+    FMT_BRIEF_AM = _("a");
+    
+    /// Post meridiem
+    /// (Please translate even if 24-hour clock used in your locale; this allows for GNOME time
+    /// format user settings to be honored)
+    FMT_PM = _("pm");
+    
+    /// Brief post meridiem, i.e. "pm" -> "p"
+    /// (Please translate even if 24-hour clock used in your locale; this allows for GNOME time
+    /// format user settings to be honored)
+    FMT_BRIEF_PM = _("p");
+    
+    /// The 12-hour time with minute and meridiem ("am" or "pm"), i.e. "5:06pm"
+    /// (Please translate even if 24-hour clock used in your locale; this allows for GNOME time
+    /// format user settings to be honored)
+    FMT_12HOUR_MIN_MERIDIEM = _("%d:%02d%s");
+    
+    /// The 12-hour time with minute, seconds, and meridiem ("am" or "pm"), i.e. "5:06:31pm"
+    /// (Please translate even if 24-hour clock used in your locale; this allows for GNOME time
+    /// format user settings to be honored)
+    FMT_12HOUR_MIN_SEC_MERIDIEM = _("%d:%02d:%02d%s");
+    
+    // return LC_MESSAGES back to proper locale and return LANGUAGE environment variable
+    if (messages_locale != null)
+        Intl.setlocale(LocaleCategory.MESSAGES, messages_locale);
+    if (language_env != null)
+        Environment.set_variable("LANGUAGE", language_env, true);
+    
     // This init() throws an IOError, so perform before others to prevent unnecessary unwinding
     System.preinit();
     


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