In 14 of our 42 languages, the plural form called "one" is not just for 1
Languages
An app's string "One habit left today" has a plural partner, "%d habits left today". Android picks between them by category: English uses "one" for 1 and "other" for everything else. In Russian the category "one" is used for 1, 21, 31, 41 and so on. Our translation check got that wrong twice on the same day, once in each direction.
The right translation it refused
On 2 November we ran our translation kit on its example app again. For Russian "one" the model wrote "Осталась %d привычка на сегодня": "%d habit left today", with the number. Our check compared it with the English "one" form, found a %d that the English did not have, and refused it as an invented placeholder. The model was right. A user with 21 habits left gets this form, so it has to show the number. We changed the check: a form may add the count that the English "other" form uses. The next run wrote all 350 strings of the example.
The wrong translation it would have passed
The same check let the opposite through. If the model had written "Осталась одна привычка" ("one habit left"), nothing in the string was lost, so it passed, and the user with 21 habits left would have been told they have one. The old rule allowed any "one" form to drop the number, because in English "one" is only 1.
Now the check knows which numbers each category covers, from CLDR, the Unicode plural rules that Android and ICU use. A form for a category that covers several numbers must show the number. A form for a single number may leave it out: German "one" is only 1, so "Noch eine Gewohnheit" is fine there.
Where "one" is not just 1
In 14 of the 41 target languages that CLDR's data in Babel 2.10 knows, "one" covers more than the number 1:
- 1, 21, 31, 41…: Russian, Ukrainian, Serbian, Macedonian.
- 0 and 1: French, Portuguese, Persian, Armenian, Kannada, Punjabi, Amharic. "Une habitude restante" would be shown for 0 habits.
- 1 and 11: Scottish Gaelic. 1, 101, 201…: Slovenian, whose "two" is also 102 and 202.
- Every number that does not end in 4, 6 or 9: Filipino.
In ICU messages a branch of its own changes this. With =0{…} in the message, French "one" is left with only 1, and the check takes that into account.
Checked against Android's own strings
Before shipping the rule we ran it on the plural messages in Android's framework strings: 897 translations in 39 of our languages. It flagged none. Google's translators put the number in every branch that covers several numbers, Russian "one" included, even where English gives 1 a branch of its own. When we took the number out of one Russian "one" branch by hand, the check said the form is also used for 21, 31, 41 and 51.
The rule is in translation-checks 1.2.0, free on GitHub, for ICU messages, and in Polyglot 1.2.0 for Android plurals and ICU messages alike. The other checks we added this week are in the note about letters of another script.