Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the ordinal suffix of a number for many languages in Java or Groovy

I am building a multi-languages grails website and I need to get the ordinal suffix of a number for several languages like English, French, Spanish, German and Italian.

I believe that this issue is quite common for multi-languages website owners. I have found this article that provides a solution but it is English only.

For instance:

/**
 *@value number 
 *@locale Current locale
 *@returns ordinal suffix for the given number
**/
public static String getOrdinalFor(int value, Locale locale) 

will give the following results:

 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"

Do you know a library (in Java or Groovy) that can help this? Or do you know an algorithm that implements it?

like image 966
fabien7474 Avatar asked Jan 15 '10 12:01

fabien7474


2 Answers

I think in many languages this approach is impossible as they simply have no concept of ordinals that can be composed of a number with some letters as extension. For "1st" i.e. in german you can only either write "1." or "erster"/"erste"/"erstes" depending of genus of what you are numbering.

like image 129
x4u Avatar answered Oct 04 '22 02:10

x4u


Unless you can apply a rule across every language, it is common to try to sidestep complex linguistic issues. You have to consider not only the number and its ordinal, but the context in which it appears and even how position within a sentence might affect translation.

Rather than try to write "1st place", a resource like this is much easier to translate:

#easyToTranslate_en.properties
label.position=Position: {0,number,integer}

Depending on what you're trying to do, you may be able to compromise with a solution like this:

#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}

This would require the code reading the resource to perform a case test to choose which resource to load.

like image 34
McDowell Avatar answered Oct 04 '22 01:10

McDowell