⬆️ ⬇️

Declination of nouns with numerals

In English, everything is simple: 1 year, 2 years, ... N years

“Russian language” is so complicated that in it nouns after numerals sometimes appear in bizarre forms. For example, 0 years, 1 year, 2 years, 3 years, 4 years, 5 years, ..., 11 years, 12 years, .., 21 years.





We needed to display budgets for tasks in various forms. For example, a project budget can be expressed as 1.5 years, and a task budget as 12 hours or 20 minutes. With hours and minutes rolled, if you squint, the form is 50 minutes (s), but you can not record 1.5 year (a, years).



For output formatting in Java, there is a wonderful class java.text.ChoiceFormat, which in string form looks like this: "{0, choice, 0 # {0, number, integer} years | 1 # {0, number, integer} year | 1 <{0, number, integer} years} ". Those. ChoiceFormat simply sets the limits for the parameter. In what range the parameter falls, that format is used.

For the Russian language, this approach is not applicable (see the example above). What to do? Write your MessageFormat and ChoiceFormat? Classes are very complex and contain calls to methods of classes that are available only in package java.text. And in general, I would not like to do special processing separately for the Russian language. It is not enough in the world of languages ​​with similar problems?

')

By the method of trial, error and serious thoughts, the following solution was obtained:



The site Xpoint.ru was found the following code in PHP, which was discussed at Habré and was called the invention of the bike. I, as an avid cyclist, could not help invent my own :)



<?

function pluralForm($n, $form1, $form2, $form5)

{

$n = abs($n) % 100;

$n1 = $n % 10;

if ($n > 10 && $n < 20) return $form5;

if ($n1 > 1 && $n1 < 5) return $form2;

if ($n1 == 1) return $form1;

return $form5;

}



//

echo " $n ".pluralForm($n, "", "", "");

?>





This code has been translated into the HourFormatter class method, which we are engaged in in analyzing person-years.



private Integer plurals(Long n){

if (n==0) return 0;

n = Math.abs(n) % 100;

Long n1 = n % 10;

if (n > 10 && n < 20) return 5;

if (n1 > 1 && n1 < 5) return 2;

if (n1 == 1) return 1;

return 5;

}





He returns, however, not “no letters”, but numbers. Because ChoiceFormat works with numbers, not letters.



Here is the original property in language_en.properties:



BUDGET_FORMAT={0,choice,0#|0<{0,number,'#.###'} |1#{0,number,integer} |1<{0,number,'#.###'} |5#{0,number,'#.###'} } {1,choice,0#|0<{1,number,'#.###'} |1#{1,number,integer} |1<{1,number,'#.###'} |5#{1,number,'#.###'} }



It is in language_en.properties:



BUDGET_FORMAT={0,choice,0#|0<{0,number,'#.###'} years|1#{0,number,integer} year|1<{0,number,'#.###'} years {1,choice,0#|0<{1,number,'#.###'} months|1#{1,number,integer} month|1<{1,number,'#.###'} months





Now you need to somehow use the plurals method to display the correct form so that the English form does not suffer.

The idea is to transfer the results of the calculation of plurals with additional parameters.



public String getString() {

// :

Integer year = plurals(getYears().intValue());

Integer month = plurals(getMonths().intValue());

return I18n.getString(this.locale, "BUDGET_FORMAT", new Object[]{getYears(), getMonths(), year, month});

}





And the property for the Russian language is as follows:



BUDGET_FORMAT={ 2 ,choice,0#|0<{0,number,'#.###'} |1#{0,number,integer} |1<{0,number,'#.###'} |5#{0,number,'#.###'} } { 3 ,choice,0#|0<{1,number,'#.###'} |1#{1,number,integer} |1<{1,number,'#.###'} |5#{1,number,'#.###'} }





That's all.



UPD. As it turned out - not all.



I was told that there is also the GNU gettext library (also implemented for Java), which can handle plural nouns. There is also Gettext Commons , where it is detailed in detail how to fasten everything to the existing code.



The library has interesting features:



System.out.println(i18n.trc("chat (verb)", "chat"));

System.out.println(i18n.trc("chat (noun)", "chat"));





True, I never found how to perform the original task with the formatting time.



Source: https://habr.com/ru/post/37579/



All Articles