-
Notifications
You must be signed in to change notification settings - Fork 967
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add russian translation for ToWords #147
Changes from 1 commit
1ef992c
b9de703
c68c123
a5e8703
3f6022e
3ed2e70
70f671e
86639b3
ae307cf
3038f61
4881068
5726da0
9564796
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
using Xunit; | ||
using Xunit.Extensions; | ||
|
||
namespace Humanizer.Tests.Localisation.ruRU | ||
{ | ||
public class NumberToWordsTests : AmbientCulture | ||
{ | ||
public NumberToWordsTests() : base("ru-RU") { } | ||
|
||
[InlineData(0, "ноль")] | ||
[InlineData(1, "один")] | ||
[InlineData(10, "десять")] | ||
[InlineData(11, "одиннадцать")] | ||
[InlineData(12, "двенадцать")] | ||
[InlineData(13, "тринадцать")] | ||
[InlineData(14, "четырнадцать")] | ||
[InlineData(15, "пятнадцать")] | ||
[InlineData(16, "шестнадцать")] | ||
[InlineData(17, "семнадцать")] | ||
[InlineData(18, "восемнадцать")] | ||
[InlineData(19, "девятнадцать")] | ||
[InlineData(20, "двадцать")] | ||
[InlineData(30, "тридцать")] | ||
[InlineData(40, "сорок")] | ||
[InlineData(50, "пятьдесят")] | ||
[InlineData(60, "шестьдесят")] | ||
[InlineData(70, "семьдесят")] | ||
[InlineData(80, "восемьдесят")] | ||
[InlineData(90, "девяносто")] | ||
[InlineData(100, "сто")] | ||
[InlineData(200, "двести")] | ||
[InlineData(300, "триста")] | ||
[InlineData(400, "четыреста")] | ||
[InlineData(500, "пятьсот")] | ||
[InlineData(600, "шестьсот")] | ||
[InlineData(700, "семьсот")] | ||
[InlineData(800, "восемьсот")] | ||
[InlineData(900, "девятьсот")] | ||
[InlineData(1000, "одна тысяча")] | ||
[InlineData(2000, "две тысячи")] | ||
[InlineData(3000, "три тысячи")] | ||
[InlineData(4000, "четыре тысячи")] | ||
[InlineData(5000, "пять тысячь")] | ||
[InlineData(10000, "десять тысячь")] | ||
[InlineData(100000, "сто тысячь")] | ||
[InlineData(1000000, "один миллион")] | ||
[InlineData(2000000, "два миллиона")] | ||
[InlineData(10000000, "десять миллионов")] | ||
[InlineData(100000000, "сто миллионов")] | ||
[InlineData(1000000000, "один миллиард")] | ||
[InlineData(2000000000, "два миллиарда")] | ||
//[InlineData(5000000000, "пять миллиардов")] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this commented out? We should either make it work or remove it from the test cases. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That could be a breaking change. So let's leave it out for now. |
||
|
||
[InlineData(122, "сто двадцать два")] | ||
[InlineData(3501, "три тысячи пятьсот один")] | ||
[InlineData(111, "сто одиннадцать")] | ||
[InlineData(1112, "одна тысяча сто двенадцать")] | ||
[InlineData(11213, "одиннадцать тысячь двести тринадцать")] | ||
[InlineData(121314, "сто двадцать одна тысяча триста четырнадцать")] | ||
[InlineData(2132415, "два миллиона сто тридцать две тысячи четыреста пятнадцать")] | ||
[InlineData(12345516, "двенадцать миллионов триста сорок пять тысячь пятьсот шестнадцать")] | ||
[InlineData(751633617, "семьсот пятьдесят один миллион шестьсот тридцать три тысячи шестьсот семнадцать")] | ||
[InlineData(1111111118, "один миллиард сто одиннадцать миллионов сто одиннадцать тысячь сто восемнадцать")] | ||
[InlineData(-751633617, "минус семьсот пятьдесят один миллион шестьсот тридцать три тысячи шестьсот семнадцать")] | ||
[Theory] | ||
public void ToWords(int number, string expected) | ||
{ | ||
Assert.Equal(expected, number.ToWords()); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace Humanizer.Localisation.NumberToWords | ||
{ | ||
internal class RussianNumberToWordsConverter : DefaultNumberToWordsConverter | ||
{ | ||
private enum GrammaticalGender | ||
{ | ||
Masculine, | ||
Feminine, | ||
Neuter | ||
} | ||
|
||
private enum GrammaticalNumber | ||
{ | ||
Singular, | ||
Paucal, | ||
Plural | ||
} | ||
|
||
private static GrammaticalNumber ToRussianGrammaticalNumber(int number) | ||
{ | ||
var mod100 = number % 100; | ||
if (mod100 / 10 != 1) | ||
{ | ||
var mod10 = number % 10; | ||
|
||
if (mod10 == 1) // 1, 21, 31, 41 ... 91, 101, 121 .. | ||
return GrammaticalNumber.Singular; | ||
|
||
if (mod10 > 1 && mod10 < 5) // 2, 3, 4, 22, 23, 24 ... | ||
return GrammaticalNumber.Paucal; | ||
} | ||
|
||
return GrammaticalNumber.Plural; | ||
} | ||
|
||
private static string ToWordsUnderThousand(int number, GrammaticalGender gender) | ||
{ | ||
var parts = new List<string>(); | ||
|
||
var hunderdsMap = new[] { "ноль", "сто", "двести", "триста", "четыреста", "пятьсот", "шестьсот", "семьсот", "восемьсот", "девятьсот" }; | ||
var hunderds = number / 100; | ||
if (hunderds > 0) | ||
{ | ||
parts.Add(hunderdsMap[hunderds]); | ||
number %= 100; | ||
} | ||
|
||
var tens = number / 10; | ||
if (tens > 1) | ||
{ | ||
var tensMap = new[] { "ноль", "десять", "двадцать", "тридцать", "сорок", "пятьдесят", "шестьдесят", "семьдесят", "восемьдесят", "девяносто" }; | ||
parts.Add(tensMap[tens]); | ||
number %= 10; | ||
} | ||
|
||
if (number > 0) | ||
{ | ||
if (number == 1 && gender == GrammaticalGender.Feminine) | ||
parts.Add("одна"); | ||
else if (number == 1 && gender == GrammaticalGender.Neuter) | ||
parts.Add("одно"); | ||
else if (number == 2 && gender == GrammaticalGender.Feminine) | ||
parts.Add("две"); | ||
else | ||
{ | ||
var unitsMap = new[] { "ноль", "один", "два", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять", "десять", "одиннадцать", "двенадцать", "тринадцать", "четырнадцать", "пятнадцать", "шестнадцать", "семнадцать", "восемнадцать", "девятнадцать" }; | ||
if (number < 20) | ||
parts.Add(unitsMap[number]); | ||
} | ||
} | ||
|
||
return string.Join(" ", parts.ToArray()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not need |
||
} | ||
|
||
public override string Convert(int number) | ||
{ | ||
if (number == 0) | ||
return "ноль"; | ||
|
||
if (number < 0) | ||
return string.Format("минус {0}", Convert(-number)); | ||
|
||
var parts = new List<string>(); | ||
|
||
var milliards = number / 1000000000; | ||
if (milliards > 0) | ||
{ | ||
var map = new[] { "миллиард", "миллиарда", "миллиардов" }; | ||
var grammaticalNumber = ToRussianGrammaticalNumber(milliards); | ||
parts.Add(string.Format("{0} {1}", ToWordsUnderThousand(milliards, GrammaticalGender.Masculine), map[(int)grammaticalNumber])); | ||
number %= 1000000000; | ||
} | ||
|
||
var millions = number / 1000000; | ||
if (millions > 0) | ||
{ | ||
var map = new[] { "миллион", "миллиона", "миллионов" }; | ||
var grammaticalNumber = ToRussianGrammaticalNumber(millions); | ||
parts.Add(string.Format("{0} {1}", ToWordsUnderThousand(millions, GrammaticalGender.Masculine), map[(int)grammaticalNumber])); | ||
number %= 1000000; | ||
} | ||
|
||
var thousands = number / 1000; | ||
if (thousands > 0) | ||
{ | ||
var map = new[] { "тысяча", "тысячи", "тысячь" }; | ||
var grammaticalNumber = ToRussianGrammaticalNumber(thousands); | ||
parts.Add(string.Format("{0} {1}", ToWordsUnderThousand(thousands, GrammaticalGender.Feminine), map[(int)grammaticalNumber])); | ||
number %= 1000; | ||
} | ||
|
||
if (number > 0) | ||
{ | ||
parts.Add(ToWordsUnderThousand(number, GrammaticalGender.Masculine)); | ||
} | ||
|
||
return string.Join(" ", parts.ToArray()); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Holy crap!! ;)