Skip to content

fix(ru,uk,be): correct plural form for counts ending in 11-14#288

Open
spokodev wants to merge 1 commit into
hustcc:masterfrom
spokodev:fix/timeago-hunt
Open

fix(ru,uk,be): correct plural form for counts ending in 11-14#288
spokodev wants to merge 1 commit into
hustcc:masterfrom
spokodev:fix/timeago-hunt

Conversation

@spokodev

@spokodev spokodev commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

The Russian, Ukrainian and Belarusian plural selectors decide the "one" and "few" forms with n > 20 / n < 10 heuristics. Those checks skip the teens once you pass 100, so any count whose last two digits are 11-14 gets the wrong form. In East-Slavic grammar 11-14 always take the "many" form, regardless of the hundreds.

Since seconds/minutes/hours/days/weeks/months are capped below 100, this only surfaces on year counts, e.g.:

import { format } from 'timeago.js';
const d = Date.now() - 112 * 366 * 24 * 60 * 60 * 1000;
format(d, 'ru'); // "112 года назад"  -> should be "112 лет назад"
format(d, 'uk'); // "112 роки тому"   -> should be "112 років тому"
format(d, 'be'); // "112 гады таму"   -> should be "112 гадоў таму"
// 111 is also wrong: ru gives "111 год назад" instead of "111 лет назад"

Oracle - Intl.RelativeTimeFormat / Intl.PluralRules (CLDR): 111, 112, 113, 114 are all category many in ru/uk/be, so they must use the same form as 5-20 ("лет"/"років"/"гадоў"), not the "one"/"few" forms.

The fix guards the 11-14 range with n % 100, the same approach sr.ts already uses in this repo. Verified against Intl.PluralRules('ru') over 1..100000: the old code mismatched 3996 values, the new code mismatches 0, and behaviour only changes for counts ending in 11-14 in the hundreds (111-114, 211-214, ...). All existing values (1, 2-4, 5-20, 21-24, ...) are unchanged.

Adds a regression test to each locale's spec.

The plural selector used `n > 20` / `n < 10` heuristics that skip the
teens in the higher hundreds, so counts such as 112 years rendered with
the "few" form (112 года/роки/гады) instead of the required "many" form
(112 лет/років/гадоў). Guard the 11-14 range with `n % 100`, matching
CLDR (Intl.PluralRules) and this repo's own sr.ts.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant