我正在构建一个多语言 grails 网站,我需要获得英语,法语,西班牙语,德语和意大利语等多种语言的序号后缀
我认为这个问题对于多语言网站所有者来说非常普遍。我发现this article提供了一个解决方案,但它只是英文版。
例如:
/**
*@value number
*@locale Current locale
*@returns ordinal suffix for the given number
**/
public static String getOrdinalFor(int value, Locale locale)
将给出以下结果:
assert getOrdinalFor(1, Locale.ENGLISH) == "st"
assert getOrdinalFor(1, Locale.FRENCH) == "er"
assert getOrdinalFor(2, Locale.ENGLISH) == "nd"
assert getOrdinalFor(3, Locale.ENGLISH) == "rd"
assert getOrdinalFor(4, Locale.ENGLISH) == "th"
assert getOrdinalFor(4, Locale.FRENCH) == "ème"
你知道一个可以帮助它的库(用Java或Groovy)吗?或者您知道实现它的算法吗?
答案 0 :(得分:3)
我认为在许多语言中这种方法是不可能的,因为它们根本没有可用由一些字母作为扩展的数字组成的序数概念。对于“1st”,即德语,你只能写“1”。或“erster”/“erste”/“erstes”取决于您编号的属。
答案 1 :(得分:1)
除非您可以对每种语言应用规则,否则通常会尝试回避复杂的语言问题。你不仅要考虑数字及其序数,还要考虑它出现的背景,甚至句子中的位置如何影响翻译。
而不是尝试编写“1st place”,这样的资源更容易翻译:
#easyToTranslate_en.properties
label.position=Position: {0,number,integer}
根据您尝试做的事情,您可能会对此类解决方案妥协:
#compromise_en.properties
label.position.first=1st place
label.position.second=2nd place
label.position.third=3rd place
label.position.default=Position: {0,number,integer}
这将需要读取资源的代码执行案例测试以选择要加载的资源。
答案 2 :(得分:0)
我不知道任何库,但最好的算法可能是在Map<Integer, Map<Locale, String>>
中掌握所有可能的数字/语言环境/序数。
private static Map<Integer, Map<Locale, String>> ordinals = new HashMap<Integer, Map<Locale, String>>();
static {
Map<Locale, String> ordinal1 = new HashMap<Locale, String>();
ordinal1.put(Locale.ENGLISH, "st");
ordinal1.put(Locale.FRENCH, "er");
ordinals.put(1, ordinal1);
Map<Locale, String> ordinal2 = new HashMap<Locale, String>();
ordinal2.put(Locale.ENGLISH, "nd");
ordinals.put(2, ordinal2);
Map<Locale, String> ordinal3 = new HashMap<Locale, String>();
ordinal3.put(Locale.ENGLISH, "rd");
ordinals.put(3, ordinal3);
Map<Locale, String> ordinal4 = new HashMap<Locale, String>();
ordinal4.put(Locale.ENGLISH, "th");
ordinal4.put(Locale.FRENCH, "ème");
ordinals.put(4, ordinal4);
}
getOrdinalFor()
基本上可能看起来像(明显的运行时错误处理除外):
public static String getOrdinalFor(int value, Locale locale) {
return ordinals.get(value).get(locale);
}
对于地图未涵盖的其他数字,您可以考虑倒数,直到在地图中找到匹配为止(因此请求例如5
或更高的序数将返回{的序数{1}}(倒计时的第一个下一个匹配)):
4
答案 3 :(得分:0)
int index = 2;
ChoiceFormat choiceFormat = new ChoiceFormat("1#st | 2#nd | 3#rd | 20<th");
String output = index + choiceFormat.format(index);
输出=='第二' 但我正在尝试编写一条规则,确保数字21-> 23,31-> 33等也能正常工作。有人知道如何使用传递给ChoiceFormat的模式吗?