Skip to content

Commit 93b66cd

Browse files
author
Oren Novotny
authored
Merge pull request #867 from sonbua/master
Add support for ToWords and ToOrdinalWords in Vietnamese culture
2 parents 6a8b106 + 294b12a commit 93b66cd

File tree

5 files changed

+214
-2
lines changed

5 files changed

+214
-2
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ _ReSharper*/
5353
*.[Rr]e[Ss]harper
5454
*.DotSettings.user
5555

56+
# JetBrains IDE
57+
.idea/
58+
5659
# JustCode is a .NET coding add-in
5760
.JustCode
5861

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using Xunit;
2+
3+
namespace Humanizer.Tests.vi
4+
{
5+
[UseCulture("vi")]
6+
public class NumberToWordsTests
7+
{
8+
[Theory]
9+
[InlineData(0, "không")]
10+
[InlineData(1, "một")]
11+
[InlineData(2, "hai")]
12+
[InlineData(3, "ba")]
13+
[InlineData(4, "bốn")]
14+
[InlineData(5, "năm")]
15+
[InlineData(6, "sáu")]
16+
[InlineData(7, "bảy")]
17+
[InlineData(8, "tám")]
18+
[InlineData(9, "chín")]
19+
[InlineData(10, "mười")]
20+
[InlineData(11, "mười một")]
21+
[InlineData(14, "mười bốn")]
22+
[InlineData(15, "mười lăm")]
23+
[InlineData(21, "hai mươi mốt")]
24+
[InlineData(24, "hai mươi tư")]
25+
[InlineData(25, "hai mươi lăm")]
26+
[InlineData(50, "năm mươi")]
27+
[InlineData(55, "năm mươi lăm")]
28+
[InlineData(100, "một trăm")]
29+
[InlineData(105, "một trăm linh năm")]
30+
[InlineData(110, "một trăm mười")]
31+
[InlineData(114, "một trăm mười bốn")]
32+
[InlineData(115, "một trăm mười lăm")]
33+
[InlineData(134, "một trăm ba mươi tư")]
34+
[InlineData(500, "năm trăm")]
35+
[InlineData(505, "năm trăm linh năm")]
36+
[InlineData(555, "năm trăm năm mươi lăm")]
37+
[InlineData(1000, "một nghìn")]
38+
[InlineData(1005, "một nghìn linh năm")]
39+
[InlineData(1115, "một nghìn một trăm mười lăm")]
40+
[InlineData(10005, "mười nghìn linh năm")]
41+
[InlineData(10115, "mười nghìn một trăm mười lăm")]
42+
[InlineData(11115, "mười một nghìn một trăm mười lăm")]
43+
[InlineData(30005, "ba mươi nghìn linh năm")]
44+
[InlineData(100005, "một trăm nghìn linh năm")]
45+
[InlineData(1000000, "một triệu")]
46+
[InlineData(100001005, "một trăm triệu một nghìn linh năm")]
47+
[InlineData(1000000000, "một tỉ")]
48+
[InlineData(1111111111111111, "một triệu một trăm mười một nghìn một trăm mười một tỉ một trăm mười một triệu một trăm mười một nghìn một trăm mười một")]
49+
[InlineData(5101101101101151101, "năm tỉ một trăm linh một triệu một trăm linh một nghìn một trăm linh một tỉ một trăm linh một triệu một trăm năm mươi mốt nghìn một trăm linh một")]
50+
public void ToWords(long number, string expected)
51+
{
52+
Assert.Equal(expected, number.ToWords());
53+
}
54+
55+
[Theory]
56+
[InlineData(0, "thứ không")]
57+
[InlineData(1, "thứ nhất")]
58+
[InlineData(2, "thứ nhì")]
59+
[InlineData(3, "thứ ba")]
60+
[InlineData(4, "thứ tư")]
61+
[InlineData(5, "thứ năm")]
62+
[InlineData(6, "thứ sáu")]
63+
[InlineData(7, "thứ bảy")]
64+
[InlineData(8, "thứ tám")]
65+
[InlineData(9, "thứ chín")]
66+
[InlineData(10, "thứ mười")]
67+
[InlineData(11, "thứ mười một")]
68+
[InlineData(14, "thứ mười bốn")]
69+
[InlineData(15, "thứ mười lăm")]
70+
[InlineData(21, "thứ hai mươi mốt")]
71+
[InlineData(24, "thứ hai mươi tư")]
72+
[InlineData(25, "thứ hai mươi lăm")]
73+
public void ToOrdinalWords(int number, string expected)
74+
{
75+
Assert.Equal(expected, number.ToOrdinalWords());
76+
}
77+
}
78+
}

src/Humanizer.Tests.Shared/UseCultureAttribute.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,4 @@ public override void After(MethodInfo methodUnderTest)
8585
CultureInfo.CurrentUICulture = originalUICulture;
8686
}
8787
}
88-
89-
9088
}

src/Humanizer/Configuration/NumberToWordsConverterRegistry.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public NumberToWordsConverterRegistry()
3838
Register("sr", (culture) => new SerbianCyrlNumberToWordsConverter(culture));
3939
Register("sr-Latn", (culture) => new SerbianNumberToWordsConverter(culture));
4040
Register("nb", new NorwegianBokmalNumberToWordsConverter());
41+
Register("vi", new VietnameseNumberToWordsConverter());
4142
Register("zh-CN", new ChineseNumberToWordsConverter());
4243
Register("bg", new BolgarianNumberToWordsConverter());
4344
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
using System;
2+
3+
namespace Humanizer.Localisation.NumberToWords
4+
{
5+
internal class VietnameseNumberToWordsConverter : GenderlessNumberToWordsConverter
6+
{
7+
private const int OneBillion = 1000000000;
8+
private const int OneMillion = 1000000;
9+
10+
private static readonly string[] NumberVerbalPairs =
11+
{
12+
"", "một", "hai", "ba", "bốn", "năm", "sáu", "bảy", "tám", "chín"
13+
};
14+
15+
public override string Convert(long number)
16+
{
17+
return number == 0
18+
? "không"
19+
: ConvertImpl(number);
20+
}
21+
22+
public override string ConvertToOrdinal(int number)
23+
{
24+
return $"thứ {ConvertToOrdinalImpl(number)}";
25+
}
26+
27+
private string ConvertToOrdinalImpl(int number)
28+
{
29+
switch (number)
30+
{
31+
case 1:
32+
return "nhất";
33+
case 2:
34+
return "nhì";
35+
case 4:
36+
return "tư";
37+
default:
38+
return Convert(number);
39+
}
40+
}
41+
42+
private static string ConvertImpl(long number, bool hasTens = false, bool isGreaterThanOneHundred = false)
43+
{
44+
if (number >= OneBillion)
45+
{
46+
return string.Format(
47+
"{0} tỉ {1}",
48+
ConvertImpl(number / OneBillion),
49+
ConvertImpl(number % OneBillion, isGreaterThanOneHundred: true)
50+
)
51+
.TrimEnd();
52+
}
53+
54+
if (number >= OneMillion)
55+
{
56+
return string.Format(
57+
"{0} triệu {1}",
58+
ConvertImpl(number / OneMillion),
59+
ConvertImpl(number % OneMillion, isGreaterThanOneHundred: true)
60+
)
61+
.TrimEnd();
62+
}
63+
64+
if (number >= 1000)
65+
{
66+
return string.Format(
67+
"{0} nghìn {1}",
68+
ConvertImpl(number / 1000),
69+
ConvertImpl(number % 1000, isGreaterThanOneHundred: true)
70+
)
71+
.TrimEnd();
72+
}
73+
74+
if (number >= 100)
75+
{
76+
return string.Format(
77+
"{0} trăm {1}",
78+
NumberVerbalPairs[number / 100],
79+
ConvertImpl(number % 100, isGreaterThanOneHundred: true)
80+
)
81+
.TrimEnd();
82+
}
83+
84+
if (number >= 20)
85+
{
86+
return string.Format(
87+
"{0} mươi {1}",
88+
NumberVerbalPairs[number / 10],
89+
ConvertImpl(number % 10, hasTens: true)
90+
)
91+
.TrimEnd();
92+
}
93+
94+
if (number == 14)
95+
{
96+
return "mười bốn";
97+
}
98+
99+
if (number == 11)
100+
{
101+
return "mười một";
102+
}
103+
104+
if (number >= 10)
105+
{
106+
return $"mười {ConvertImpl(number % 10, hasTens: true)}".TrimEnd();
107+
}
108+
109+
if (number == 5 && hasTens)
110+
{
111+
return "lăm";
112+
}
113+
114+
if (number == 4 && hasTens)
115+
{
116+
return "tư";
117+
}
118+
119+
if (number == 1 && hasTens)
120+
{
121+
return "mốt";
122+
}
123+
124+
if (number > 0 && isGreaterThanOneHundred && !hasTens)
125+
{
126+
return $"linh {NumberVerbalPairs[number]}";
127+
}
128+
129+
return NumberVerbalPairs[number];
130+
}
131+
}
132+
}

0 commit comments

Comments
 (0)