Localisation capabilities of the RelativeTime plugin are insufficient for fusional languages
See original GitHub issueWhat do you think about re-working the current locale definition of the RelativeTime plugin to support fusional languages without grammatical mistakes?
Moment.js has more complicated locale definitions, but it allows grammatically correct localisation for Slavic languages, for example. Your Russian localisation suffers from the second problem below and my Czech localisation from both, which makes the localised expressions look so wrong, that they cannot be used in real-world applications.
Problem
- Localisation expressions for future (“after %s”) and past (“before %s”) contain the same rest of the expression. However, they contain different prepositions and thus they may need different declension in the rest of the expression.
- There is only one localisation expression for multiple seconds (“%d seconds”), minutes (“%d minutes”) etc. However, different numerals may need different declension of the following noun.
For example, Slavic languages do not use just one noun form for singlular (one second) and one for plural (many seconds). Usually there are different forms after numerals 1, 2-4 and 5+. Additionally, the noun changes according to to the grammatical case, which is needed in the particular expression. The grammatical case depends on the preposition, for example.
Examples of English, German Russian and Czech expressions
Years - Past
a year ago vor einem Jahr в прошлом году vloni (před rokem)
2 years ago vor 2 Jahren 2 года назад před 2 roky
5 years ago vor 5 Jahren 5 лет назад před 5 lety
Years - Future
in a year in einem Jahr через год za rok
in 2 years in 2 Jahren через 2 года za 2 roky
in 5 years in 5 Jahren через 5 лет za 5 let
Days - Past
yesterday gestern вчера včera
(a day ago vor einem Tag) день назад před jedním dnem)
2 days ago vor 2 Tagen 2 дни назад před 2 dny
5 days ago vor 5 Tagen 5 дней назад před 5 dny
Days - Future
tomorrow morgen завтра zítra
(in a day in einem Tag через день za den)
in 2 days in 2 Tagen через 2 дни za 2 dny
in 5 days in 5 Tagen через 5 дней za 5 dní
Seconds - Past
a second ago vor einer Sekonde секунду назад před sekundou
2 seconds ago vor 2 Sekonden 2 секунды назад před 2 sekundami
5 seconds ago vor 5 Sekonden 5 секунд назад před 5 sekundami
a couple of seconds ago vor wenigen Sekonden несколько секунд назад před pár (několika) sekundami
Seconds - Future
in a second in einer Sekonde через секунду za sekundu
in 2 seconds in 2 Sekonden через 2 секунды za 2 sekundy
in 5 seconds in 5 Sekonden через 5 секунд za 5 sekund
in a couple of seconds in wenigen Sekonden через несколько секунд za pár (několik) sekund
Solution
- Duplicate all expressions for future and past instead of combining them with the two prepositions.
- Introduce the third expression with the numeral for many (5). Use the current expressions for one (1) and few (2-4).
const locale = {
name: 'cs',
weekdays: 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),
months: 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'),
ordinal: n => `${n}.`,
relativeTime: {
future: {
s: 'za několik sekund',
m: 'za minutu',
mm: 'za %d minuty',
mmm: 'za %d minut',
h: 'za hodinu',
hh: 'za %d hodiny',
hhh: 'za %d hodin',
d: 'zítra',
dd: 'za %d dny',
ddd: 'za %d dní',
M: 'za měsíc',
MM: 'za %d měsíce',
MMM: 'za %d měsícú',
y: 'za rok',
yy: 'za %d roky',
yyy: 'za %d let'
},
past: {
s: 'před několika sekundami',
m: 'před minutou',
mm: 'před %d minutami',
mmm: 'před %d minutami',
h: 'před hodinu',
hh: 'před %d hodinami',
hhh: 'před %d hodinami',
d: 'včera',
dd: 'před %d dny',
ddd: 'před %d dny',
M: 'před měsícem',
MM: 'před %d měsíci',
MMM: 'před %d měsíci',
y: 'vloni',
yy: 'před %d roky',
yyy: 'před %d lety'
}
}
}
Issue Analytics
- State:
- Created 5 years ago
- Reactions:8
- Comments:5 (5 by maintainers)
Top GitHub Comments
My original simplification was not enough. Even the common languages were not covered well with the three plural forms and the single rule for them, as @leovp pointed out.
It would be better to go for the universal solution right away instead of trying something simpler as I did originally. For example, by specifying both the plural rule (a number or a function) and the plural forms as an array of strings, which the plural rule is an index to.
I had to to separate the special singular form from the plural forms. It has usually no number and thus the first plural form (for 1, 21, 31, …) cannot be reused for it.
I updated #304 with this approach.
Eventually, the plural rules should make it out of the
relativeTime
plugin to thedayjs
core utilities. Or may be event out of this module.@limonte, I took care not to break the existing language packs in the suggested fix #304. Czech, Slovak, Russian and Ukrainian language packs are updated. The others are loaded and work as they did before the change. They can be gradually upgraded as the community goes on.
I reused the existing patterns “m” and “mm” for the mnemonic tags “one” and “few”. I added pattern “mmm” for the “many” tag. Tag “zero” is not needed for relative time values. Tag “two” is rare and tag “other” has no common rules. Tags “one”, “few” and “many” hardcoded for 1, 2-4 and 5+ numbers mean a small change and cover many languages. The future step could be implementing the full CLDR rules. See plural rules on CLDR for more information.)