- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图找出为什么 GNU gettext 的行为不像 strftime
或printf
当谈到本地化时。我从头到尾阅读了整个手册,但示例相当简单。我已将问题简化为一个简单的 C 程序。
任务是通过用户输入切换应用程序中的区域设置以接收本地化文件输出。
我的区域设置:
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 搜索后,我发现 bindtextdomain
和/或 textdomain
必须在每个 setlocale
之后执行。而且,我还要执行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
最佳答案
您需要调用bindtextdomain()
的主要原因在setlocale()
之后调用,正在缓存。
如果每个 gettext()
调用来检查环境变量,这会很慢。也许对于今天的机器来说它不会引人注目,但它曾经非常重要。相反,当您发出 bindtextdomain()
调用时,就会完成(区域设置)查找,并缓存结果,以提高效率。
在实践中,存在..缺点。特别是,LANGUAGE
环境变量会影响每个 gettext()
调用。此外,gettext
不
支持线程特定的区域设置(通过 uselocale()
GNU 扩展)——在 Linux 中,使用 glibc 2.4 或更高版本(2006 年发布)时,以及自 2013 年以来的 macOS/Mac OSX 中或左右。 (编辑:我在此之前就开始使用 gettext,只是没能跟上最新的情况;我做了一些我不应该做的假设。抱歉。)由于 gettext 的初始版本早在 1990 年就发布了,并且从那时到现在,很多东西都发生了变化,你也可以考虑这个历史包袱,甚至是一个错误。
关于c - 与 strftime 或 printf 相比,GNU gettext 的本地化行为不稳定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40302497/
“strftime”中的“strf”是什么意思?我在谷歌上搜索了很多次这个问题,但没有找到答案。知道这些字母代表什么会让我更容易记住这个函数的名称。 最佳答案 来自 man 3 strftime :
我制作了这个脚本来跟踪我当前的时间和当前的电池百分比(然后将其附加到剪贴板,以便我可以将其粘贴到某个地方): from tkinter import * from urllib import pars
我想从我的 Sqlite 数据库中的日期时间列中获取一个月中的某一天。我可以简单地使用 select strftime('%d',myColumn) from myTable 但是这些值以 UTC 格
我编写了一个 perl 脚本,我在其中调用一个子例程将字段插入到数据库表中。该子例程在除主 perl 文件 Test.pl 之外的另一个文件 Test.pm 中调用。在 Test.pm 中,我将以下字
我们有一个 C++/MFC 应用程序,它允许用户通过配置文件自定义日期格式。不想重新发明轮子,我将格式字符串传递给 CTime::Format("") 以进行实际格式化。在幕后,Format 调用了标
下面列出了两行代码。两者对日期和时间的期望相同,但只有一个有效。我正在使用 R 3.1。 以下不起作用: DateTime2=strftime("08/13/2010 05:26:24.350", f
我使用strftime获得ISO 8601格式(%V)的星期数,并希望转换为前景中显示的星期数(猜测是格里高利历法)。 Outlook日历设置为: 一周的第一天(星期日) 一年的第一周1月1日开始 在
为什么此页面的代码不起作用?:http://strftime.org/ 。我想输出不带前导零的日期和月份,例如 'm/d/yyyy' 例如:“1992 年 4 月 5 日”是 '04/05/1992'
谁能告诉我为什么时区返回为“山区夏令时间”而不是 MST ? import time print time.strftime( "%H:%M %A %Z %d %b %y") 最佳答案 根据您提出的另
我正在尝试更新一些 csv 文件,稍后再更新我的数据库。看来每个月的 strftime 都会混淆一天。我在德国,我们写的是日期 DD/MM/YYYY 而不是 MM/DD/YYYY。 如何从 germa
我当前的计算机显示 CET 时间: $ date Mon Dec 1 21:31:41 CET 2014 但是我的区域设置是 en_US: $ locale | grep -i time LC_TI
strftime('%s', 'now', 'start of month') AND strftime('%s', 'now', 'start of month', '+1 month', '-1
我正在使用以下日期格式: d.strftime("%A, %d %B %Y %H:%m") 并且由于工作日的长度 (%A) 发生了变化,我想总是打印工作日10个字符,左边补空格,右对齐。 有点像 d.
Python3 strftime 产生的结果因平台而异。例如: OS X 10.10.5 >>> sys.version '3.5.2 (v3.5.2:4def2a2901a5, Jun 26 201
大家好,我想知道是否有人可以向我指出这一点。我目前正在尝试在 cmd 提示符的右上角显示日期和时间,但我得到的字符比我要求的要多。这是我目前所拥有的 time_t rawtime; struct tm
#include #include using namespace std; int main() { char dateStringBuffer[256] = ""; tm da
我试过 strftime( ) 来获取格式化的时间戳。 char ft[ 256 ]; struct tm *tmp; strftime( ft, 256, "%D - %T", tmp ); 我的问
char buffer[800]; struct tm str_time; str_time.tm_mday = Cur_Day; str_time.t
例如,时间戳是1403667010.574,使用Time.at(1403667010.574).strftime('%Y-%m-%d %H:%M:%S.%L %z'),则结果为 "2014-06-25
我试图将 YYYY-mm-dd 23:59:59 格式的时间保存到带有日期时间的 mysql 数据库列中。我不明白为什么总是忽略分钟和秒 00 ?非常感谢您的帮助。 PHP: $time = strf
我是一名优秀的程序员,十分优秀!