我正在制作一个我需要显示持续时间字符串的应用。几个例子:
目前我有一个C ++函数,在给定的秒数/毫秒/分钟内给你一个字符串:
wxString getTimeStr(int value,
ETimeUnit time_unit, // milliseconds or seconds or minutes or hours
wxString const & lang) // english or russian
它包含许多条件,具体取决于语言,时间单位和现有价值。现在我正在考虑将应用程序移植到其他语言中,为每种新语言编写c ++代码会有点痛苦。有没有办法使用标准函数制作该字符串?
该应用程序是使用wxWidgets以C ++编写的,目前仅适用于Windows。我宁愿不使用与平台相关的函数,尽管知道它们会很好。
答案 0 :(得分:1)
我建议将你的功能分成两部分。
第一部分将返回剩余的时间作为wxTimeSpan。
第二部分'将'wxTimeSpan'翻译成所需语言并返回一个字符串。这是您需要为每种语言更改的唯一部分。
为了便于解释,我们假设
然后你的第二个函数会写成这样的东西
// extract hours and residual minutes into CSV
wxString csv = theTimeSpan.Format("%H,%M);
// extract tokens for csv
wxString hours, mins
...
if( lang == "Klingon" ) {
return hours + "/" + mins
} else if ( lang == "Vulcan" ) {
return mins + ":" + hours
} else if ( lang == "Russian" ) {
wxString min_name;
switch( mins.ToLong() ) {
case 1: min_name = "---"; break;
...
}
return mins + " " + min_name;
}
遗憾的是,您不能使用Format来获取任意“时间结构”,因为例如时间跨度中的小时数存在重要的歧义。它可以是总小时数(例如,50小时的时间跨度为50小时),也可以是时间跨度的小时部分,在这种情况下为2小时,因为50小时等于2天和2个小时。
wxTimeSpan通过以下方式解决了这种歧义:如果确实存在H之前指定的D格式,则它被解释为2.否则,它是50.这同样适用于所有其他格式说明符:if它们遵循较大单位的说明符,仅采用其余部分,否则使用完整值。
所以,你必须使用csv令牌,如我的代码示例所示。
答案 1 :(得分:1)
如果不为不同的语言编写不同的代码,您将无法完美地完成任务。例如,我敢打赌你现有的代码不允许产生“在三点半之前的5分钟”之类的时间,这些时间仍用于(口语)德语。即使没有达到这样的延伸,也可以考虑将英语“三点半”实际翻译为“一半到四”。
因此,如果使用官方时间是不够的(如果是,请查看wxLocale::GetInfo(wxLOCALE_TIME_FMT)
),您确实需要编写代码来专门处理至少某些语言。
答案 2 :(得分:0)
解决本地化问题的传统方法是构建label name -> label value
的地图并在值中使用占位符。
根据您需要的复杂程度,您可能有一个简单的占位符机制(snprintf
- like),或者允许迷你语言在运行时根据简单参数构建值的方法(例如,区分单数和复数。)
在这个例子中,它将如下:
using LabelsType = std::map<LabelName, std::string>;
using LangToLabelsType = std::map<Language, LabelsType>;
注意:我建议使用枚举语言而不是普通字符串。
如果你在Linux上我会推荐gettext
,但我不确定它是否适用于Windows。不过,你可以查阅它,看看它是如何工作的,它可能对你有帮助。
答案 3 :(得分:0)
有时,最好让程序更具技术性而不是更接近自然语言。我也发现自己处于这种情况下(让它看起来非常酷)。通常是客户不关心的情况。这些信息有时比其确切形式重要得多。
程序员有时应该选择权衡 - 一种与编程语言/框架无关的元解决方案。换句话说,您应该权衡解决方案的正确性和期望的正确性。