Use LC_TIME locale for strftime format string translations
We commonly mark strftime format strings for translation to account for date/time representations without an existing strftime shortcut ("Yesterday %H%p"). As those translations are looked up according to the locale defined by LC_MESSAGES, while the conversion characters themselves are resolved according to LC_TIME, the result can be rather odd when mixing locales ("Den 27. January"). The correct solution would be to install translations for format strings in the LC_TIME catalogue and look them up with dcgettext(), but we don't have the infrastructure to do that easily. Work around this by adding a helper method that looks up a string in LC_MESSAGES using the locale defined by LC_TIME and use that to translate format strings, which has the same result. https://bugzilla.gnome.org/show_bug.cgi?id=738640
This commit is contained in:
parent
2f5a226bc2
commit
eb3fc7815e
@ -16,6 +16,7 @@ const SHOW_WEEKDATE_KEY = 'show-weekdate';
|
|||||||
|
|
||||||
// alias to prevent xgettext from picking up strings translated in GTK+
|
// alias to prevent xgettext from picking up strings translated in GTK+
|
||||||
const gtk30_ = Gettext_gtk30.gettext;
|
const gtk30_ = Gettext_gtk30.gettext;
|
||||||
|
const NC_ = function(context, str) { return str; };
|
||||||
|
|
||||||
// in org.gnome.desktop.interface
|
// in org.gnome.desktop.interface
|
||||||
const CLOCK_FORMAT_KEY = 'clock-format';
|
const CLOCK_FORMAT_KEY = 'clock-format';
|
||||||
@ -792,14 +793,17 @@ const EventsList = new Lang.Class({
|
|||||||
let dayBegin = _getBeginningOfDay(day);
|
let dayBegin = _getBeginningOfDay(day);
|
||||||
let dayEnd = _getEndOfDay(day);
|
let dayEnd = _getEndOfDay(day);
|
||||||
|
|
||||||
let dayString;
|
let dayFormat;
|
||||||
let now = new Date();
|
let now = new Date();
|
||||||
if (_sameYear(day, now))
|
if (_sameYear(day, now))
|
||||||
/* Translators: Shown on calendar heading when selected day occurs on current year */
|
/* Translators: Shown on calendar heading when selected day occurs on current year */
|
||||||
dayString = day.toLocaleFormat(C_("calendar heading", "%A, %B %d"));
|
dayFormat = Shell.util_translate_time_string(NC_("calendar heading",
|
||||||
|
"%A, %B %d"));
|
||||||
else
|
else
|
||||||
/* Translators: Shown on calendar heading when selected day occurs on different year */
|
/* Translators: Shown on calendar heading when selected day occurs on different year */
|
||||||
dayString = day.toLocaleFormat(C_("calendar heading", "%A, %B %d, %Y"));
|
dayFormat = Shell.util_translate_time_string(NC_("calendar heading",
|
||||||
|
"%A, %B %d, %Y"));
|
||||||
|
let dayString = day.toLocaleFormat(dayFormat);
|
||||||
this._addPeriod(dayString, 0, dayBegin, dayEnd, false, true);
|
this._addPeriod(dayString, 0, dayBegin, dayEnd, false, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ const NotificationDirection = {
|
|||||||
RECEIVED: 'chat-received'
|
RECEIVED: 'chat-received'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const N_ = function(s) { return s; };
|
||||||
|
|
||||||
function makeMessageFromTpMessage(tpMessage, direction) {
|
function makeMessageFromTpMessage(tpMessage, direction) {
|
||||||
let [text, flags] = tpMessage.to_text();
|
let [text, flags] = tpMessage.to_text();
|
||||||
|
|
||||||
@ -950,70 +952,70 @@ const ChatNotification = new Lang.Class({
|
|||||||
// Show only the time if date is on today
|
// Show only the time if date is on today
|
||||||
if(daysAgo < 1){
|
if(daysAgo < 1){
|
||||||
/* Translators: Time in 24h format */
|
/* Translators: Time in 24h format */
|
||||||
format = _("%H\u2236%M");
|
format = N_("%H\u2236%M");
|
||||||
}
|
}
|
||||||
// Show the word "Yesterday" and time if date is on yesterday
|
// Show the word "Yesterday" and time if date is on yesterday
|
||||||
else if(daysAgo <2){
|
else if(daysAgo <2){
|
||||||
/* Translators: this is the word "Yesterday" followed by a
|
/* Translators: this is the word "Yesterday" followed by a
|
||||||
time string in 24h format. i.e. "Yesterday, 14:30" */
|
time string in 24h format. i.e. "Yesterday, 14:30" */
|
||||||
// xgettext:no-c-format
|
// xgettext:no-c-format
|
||||||
format = _("Yesterday, %H\u2236%M");
|
format = N_("Yesterday, %H\u2236%M");
|
||||||
}
|
}
|
||||||
// Show a week day and time if date is in the last week
|
// Show a week day and time if date is in the last week
|
||||||
else if (daysAgo < 7) {
|
else if (daysAgo < 7) {
|
||||||
/* Translators: this is the week day name followed by a time
|
/* Translators: this is the week day name followed by a time
|
||||||
string in 24h format. i.e. "Monday, 14:30" */
|
string in 24h format. i.e. "Monday, 14:30" */
|
||||||
// xgettext:no-c-format
|
// xgettext:no-c-format
|
||||||
format = _("%A, %H\u2236%M");
|
format = N_("%A, %H\u2236%M");
|
||||||
|
|
||||||
} else if (date.getYear() == now.getYear()) {
|
} else if (date.getYear() == now.getYear()) {
|
||||||
/* Translators: this is the month name and day number
|
/* Translators: this is the month name and day number
|
||||||
followed by a time string in 24h format.
|
followed by a time string in 24h format.
|
||||||
i.e. "May 25, 14:30" */
|
i.e. "May 25, 14:30" */
|
||||||
// xgettext:no-c-format
|
// xgettext:no-c-format
|
||||||
format = _("%B %d, %H\u2236%M");
|
format = N_("%B %d, %H\u2236%M");
|
||||||
} else {
|
} else {
|
||||||
/* Translators: this is the month name, day number, year
|
/* Translators: this is the month name, day number, year
|
||||||
number followed by a time string in 24h format.
|
number followed by a time string in 24h format.
|
||||||
i.e. "May 25 2012, 14:30" */
|
i.e. "May 25 2012, 14:30" */
|
||||||
// xgettext:no-c-format
|
// xgettext:no-c-format
|
||||||
format = _("%B %d %Y, %H\u2236%M");
|
format = N_("%B %d %Y, %H\u2236%M");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Show only the time if date is on today
|
// Show only the time if date is on today
|
||||||
if(daysAgo < 1){
|
if(daysAgo < 1){
|
||||||
/* Translators: Time in 24h format */
|
/* Translators: Time in 24h format */
|
||||||
format = _("%l\u2236%M %p");
|
format = N_("%l\u2236%M %p");
|
||||||
}
|
}
|
||||||
// Show the word "Yesterday" and time if date is on yesterday
|
// Show the word "Yesterday" and time if date is on yesterday
|
||||||
else if(daysAgo <2){
|
else if(daysAgo <2){
|
||||||
/* Translators: this is the word "Yesterday" followed by a
|
/* Translators: this is the word "Yesterday" followed by a
|
||||||
time string in 12h format. i.e. "Yesterday, 2:30 pm" */
|
time string in 12h format. i.e. "Yesterday, 2:30 pm" */
|
||||||
// xgettext:no-c-format
|
// xgettext:no-c-format
|
||||||
format = _("Yesterday, %l\u2236%M %p");
|
format = N_("Yesterday, %l\u2236%M %p");
|
||||||
}
|
}
|
||||||
// Show a week day and time if date is in the last week
|
// Show a week day and time if date is in the last week
|
||||||
else if (daysAgo < 7) {
|
else if (daysAgo < 7) {
|
||||||
/* Translators: this is the week day name followed by a time
|
/* Translators: this is the week day name followed by a time
|
||||||
string in 12h format. i.e. "Monday, 2:30 pm" */
|
string in 12h format. i.e. "Monday, 2:30 pm" */
|
||||||
// xgettext:no-c-format
|
// xgettext:no-c-format
|
||||||
format = _("%A, %l\u2236%M %p");
|
format = N_("%A, %l\u2236%M %p");
|
||||||
|
|
||||||
} else if (date.getYear() == now.getYear()) {
|
} else if (date.getYear() == now.getYear()) {
|
||||||
/* Translators: this is the month name and day number
|
/* Translators: this is the month name and day number
|
||||||
followed by a time string in 12h format.
|
followed by a time string in 12h format.
|
||||||
i.e. "May 25, 2:30 pm" */
|
i.e. "May 25, 2:30 pm" */
|
||||||
// xgettext:no-c-format
|
// xgettext:no-c-format
|
||||||
format = _("%B %d, %l\u2236%M %p");
|
format = N_("%B %d, %l\u2236%M %p");
|
||||||
} else {
|
} else {
|
||||||
/* Translators: this is the month name, day number, year
|
/* Translators: this is the month name, day number, year
|
||||||
number followed by a time string in 12h format.
|
number followed by a time string in 12h format.
|
||||||
i.e. "May 25 2012, 2:30 pm"*/
|
i.e. "May 25 2012, 2:30 pm"*/
|
||||||
// xgettext:no-c-format
|
// xgettext:no-c-format
|
||||||
format = _("%B %d %Y, %l\u2236%M %p");
|
format = N_("%B %d %Y, %l\u2236%M %p");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return date.toLocaleFormat(format);
|
return date.toLocaleFormat(Shell.util_translate_time_string(format));
|
||||||
},
|
},
|
||||||
|
|
||||||
appendTimestamp: function() {
|
appendTimestamp: function() {
|
||||||
|
@ -129,7 +129,7 @@ const DateMenuButton = new Lang.Class({
|
|||||||
/* Translators: This is the date format to use when the calendar popup is
|
/* Translators: This is the date format to use when the calendar popup is
|
||||||
* shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
* shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
||||||
*/
|
*/
|
||||||
let dateFormat = _("%A %B %e, %Y");
|
let dateFormat = Shell.util_translate_time_string ("%A %B %e, %Y");
|
||||||
this._date.set_label(now.toLocaleFormat(dateFormat));
|
this._date.set_label(now.toLocaleFormat(dateFormat));
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
@ -85,7 +85,8 @@ const Clock = new Lang.Class({
|
|||||||
let date = new Date();
|
let date = new Date();
|
||||||
/* Translators: This is a time format for a date in
|
/* Translators: This is a time format for a date in
|
||||||
long format */
|
long format */
|
||||||
this._date.text = date.toLocaleFormat(_("%A, %B %d"));
|
let dateFormat = Shell.util_translate_time_string("%A, %B %d");
|
||||||
|
this._date.text = date.toLocaleFormat(dateFormat);
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <gdk/gdkx.h>
|
#include <gdk/gdkx.h>
|
||||||
#include <X11/extensions/XTest.h>
|
#include <X11/extensions/XTest.h>
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
#ifdef HAVE__NL_TIME_FIRST_WEEKDAY
|
#ifdef HAVE__NL_TIME_FIRST_WEEKDAY
|
||||||
#include <langinfo.h>
|
#include <langinfo.h>
|
||||||
#endif
|
#endif
|
||||||
@ -208,6 +209,32 @@ shell_util_get_week_start ()
|
|||||||
return week_start;
|
return week_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shell_util_translate_time_string:
|
||||||
|
* @str: String to translate
|
||||||
|
*
|
||||||
|
* Translate @str according to the locale defined by LC_TIME; unlike
|
||||||
|
* dcgettext(), the translations is still taken from the LC_MESSAGES
|
||||||
|
* catalogue and not the LC_TIME one.
|
||||||
|
*
|
||||||
|
* Returns: the translated string
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
shell_util_translate_time_string (const char *str)
|
||||||
|
{
|
||||||
|
const char *locale = g_getenv ("LC_TIME");
|
||||||
|
const char *res;
|
||||||
|
|
||||||
|
if (locale)
|
||||||
|
setlocale (LC_MESSAGES, locale);
|
||||||
|
|
||||||
|
res = gettext (str);
|
||||||
|
|
||||||
|
setlocale (LC_MESSAGES, "");
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shell_write_string_to_stream:
|
* shell_write_string_to_stream:
|
||||||
* @stream: a #GOutputStream
|
* @stream: a #GOutputStream
|
||||||
|
@ -21,6 +21,7 @@ int shell_util_get_week_start (void);
|
|||||||
|
|
||||||
char *shell_util_format_date (const char *format,
|
char *shell_util_format_date (const char *format,
|
||||||
gint64 time_ms);
|
gint64 time_ms);
|
||||||
|
const char *shell_util_translate_time_string (const char *str);
|
||||||
|
|
||||||
gboolean shell_write_string_to_stream (GOutputStream *stream,
|
gboolean shell_write_string_to_stream (GOutputStream *stream,
|
||||||
const char *str,
|
const char *str,
|
||||||
|
Loading…
Reference in New Issue
Block a user