我試圖找出爲什麼GNU的gettext的行爲是不喜歡strftime
或printf
當談到本地化。我從A到Z閱讀整個手冊,但這些例子非常簡單。我已經將問題簡化爲一個簡單的C程序。不穩定本地化行爲的gettext相比STRFTIME或printf的
的任務是通過用戶輸入來切換區域設置在應用程序中接收的局部文件輸出。
我的語言環境:
LANG=de_DE.UTF-8
LC_CTYPE="de_DE.UTF-8"
LC_COLLATE="de_DE.UTF-8"
LC_TIME="de_DE.UTF-8"
LC_NUMERIC="de_DE.UTF-8"
LC_MONETARY="de_DE.UTF-8"
LC_MESSAGES="de_DE.UTF-8"
LC_ALL=
考慮這個C示例:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <time.h>
#include <math.h>
#include "my-i18n.h"
#define PI acos(-1.0)
static char *locales[] = {
"de_DE.UTF-8",
"ru_RU.UTF-8",
"he_IL.UTF-8",
"es_ES.UTF-8",
"C",
};
void localize(char *locale, struct tm *time) {
printf("==============================================================\n");
printf("Passed locale: %s\n", locale);
char *setlocale_out = setlocale(LC_ALL, locale);
printf("Set locale: %s\n", setlocale_out);
char buffer[80];
strftime(buffer, sizeof(buffer), "%c", time);
printf("Localized time: %s\n", buffer);
printf("Get rational, π: %f\n", PI);
printf(_("Hello World!\n"));
printf(_("Goodbye!\n"));
}
int main(void) {
time_t rawtime = time(NULL);
struct tm *time;
localtime(&rawtime);
time = localtime(&rawtime);
bindtextdomain("my-i18n", LOCALEDIR);
textdomain("my-i18n");
int i;
for (i = 0; i < sizeof(locales)/sizeof(locales[0]); i++) {
localize(locales[i], time);
}
return EXIT_SUCCESS;
}
,其輸出:
==============================================================
Passed locale: de_DE.UTF-8
Set locale: de_DE.UTF-8
Localized time: Fr 28 Okt 11:44:24 2016
Get rational, π: 3,141593
Setting LANG=de_DE.UTF-8
Hallo Welt!
Tschüß!
==============================================================
Passed locale: ru_RU.UTF-8
Set locale: ru_RU.UTF-8
Localized time: пятница, 28 октября 2016 г. 11:44:24
Get rational, π: 3,141593
Setting LANG=ru_RU.UTF-8
Hallo Welt!
Tschüß!
==============================================================
Passed locale: he_IL.UTF-8
Set locale: he_IL.UTF-8
Localized time: CEST 11:44:24 2016 אוק 28 ו'
Get rational, π: 3.141593
Setting LANG=he_IL.UTF-8
Hallo Welt!
Tschüß!
==============================================================
Passed locale: es_ES.UTF-8
Set locale: es_ES.UTF-8
Localized time: vie 28 oct 11:44:24 2016
Get rational, π: 3,141593
Setting LANG=es_ES.UTF-8
Hallo Welt!
Tschüß!
==============================================================
Passed locale: C
Set locale: C
Localized time: Fri Oct 28 11:44:24 2016
Get rational, π: 3.141593
Setting LANG=C
Hallo Welt!
Tschüß!
正如你所看到的,strftime
和printf
做了什麼我的預期,但gettext只考慮我的外部區域設置。在Google和SO搜索之後,我發現每setlocale
之後必須執行bindtextdomain
和/或textdomain
。此外,我必須執行putenv("LANG=...")
強制gettext工作。
修改C代碼:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <time.h>
#include <math.h>
#include "my-i18n.h"
#define PI acos(-1.0)
static char *locales[] = {
"de_DE.UTF-8",
"ru_RU.UTF-8",
"he_IL.UTF-8",
"es_ES.UTF-8",
"C",
};
void localize(char *locale, struct tm *time) {
printf("==============================================================\n");
printf("Passed locale: %s\n", locale);
char *setlocale_out = setlocale(LC_ALL, locale);
printf("Set locale: %s\n", setlocale_out);
char buffer[80];
strftime(buffer, sizeof(buffer), "%c", time);
printf("Localized time: %s\n", buffer);
printf("Get rational, π: %f\n", PI);
printf("Setting LANG=%s\n", locale);
setenv("LANG", locale, 1);
bindtextdomain("my-i18n", LOCALEDIR);
textdomain("my-i18n");
printf(_("Hello World!\n"));
printf(_("Goodbye!\n"));
}
int main(void) {
time_t rawtime = time(NULL);
struct tm *time;
localtime(&rawtime);
time = localtime(&rawtime);
int i;
for (i = 0; i < sizeof(locales)/sizeof(locales[0]); i++) {
localize(locales[i], time);
}
return EXIT_SUCCESS;
}
和輸出:
==============================================================
Passed locale: de_DE.UTF-8
Set locale: de_DE.UTF-8
Localized time: Fr 28 Okt 11:50:33 2016
Get rational, π: 3,141593
Setting LANG=de_DE.UTF-8
Hallo Welt!
Tschüß!
==============================================================
Passed locale: ru_RU.UTF-8
Set locale: ru_RU.UTF-8
Localized time: пятница, 28 октября 2016 г. 11:50:33
Get rational, π: 3,141593
Setting LANG=ru_RU.UTF-8
Привет мир!
Пока!
==============================================================
Passed locale: he_IL.UTF-8
Set locale: he_IL.UTF-8
Localized time: CEST 11:50:33 2016 אוק 28 ו'
Get rational, π: 3.141593
Setting LANG=he_IL.UTF-8
Hello World!
Goodbye!
==============================================================
Passed locale: es_ES.UTF-8
Set locale: es_ES.UTF-8
Localized time: vie 28 oct 11:50:33 2016
Get rational, π: 3,141593
Setting LANG=es_ES.UTF-8
¡Hola mundo!
¡Adios!
==============================================================
Passed locale: C
Set locale: C
Localized time: Fri Oct 28 11:50:33 2016
Get rational, π: 3.141593
Setting LANG=C
Hello World!
Goodbye!
有人能解釋一下這個 「怪異」 的行爲?
編輯:我曾提出它在郵件列表上:http://lists.gnu.org/archive/html/bug-gettext/2016-11/msg00002.html
嗯..但'putenv'怎麼樣。即使使用'bindtextdomain',如果沒有調用'putenv',它也不起作用。這些文檔對它沒有什麼幫助。 –
@ Michael-O:我認爲這是一個bug;我隱約記得幾年前在某個地方看到了一些討論(可能是[bug-gettext](http://lists.gnu.org/archive/html/bug-gettext/)郵件列表或musl郵件列表),與我提到的那些實用疣有關。順便說一下,爲什麼不使用'setenv(「LANG」,locale,1)'而不是'putenv()'? –
這只是我在SO上找到的示例代碼。我會改變我的問題。謝謝。 –