diff --git a/src/Humanizer.Tests/Humanizer.Tests.csproj b/src/Humanizer.Tests/Humanizer.Tests.csproj index 5742d610f..8d3ec3eee 100644 --- a/src/Humanizer.Tests/Humanizer.Tests.csproj +++ b/src/Humanizer.Tests/Humanizer.Tests.csproj @@ -81,6 +81,7 @@ + diff --git a/src/Humanizer.Tests/Localisation/es/NumberToWordsFeminineTest.cs b/src/Humanizer.Tests/Localisation/es/NumberToWordsFeminineTest.cs new file mode 100644 index 000000000..6c17f8cca --- /dev/null +++ b/src/Humanizer.Tests/Localisation/es/NumberToWordsFeminineTest.cs @@ -0,0 +1,27 @@ +using Xunit; +using Xunit.Extensions; + +namespace Humanizer.Tests.Localisation.es +{ + public class NumberToWordsFeminineTests : AmbientCulture + { + public NumberToWordsFeminineTests() : base("es-ES") { } + + [Theory] + [InlineData(1, "una")] + [InlineData(21, "veintiuna")] + [InlineData(31, "treinta y una")] + [InlineData(81, "ochenta y una")] + [InlineData(500, "quinientas")] + [InlineData(701, "setecientas una")] + [InlineData(3500, "tres mil quinientas")] + [InlineData(200121, "doscientas mil ciento veintiuna")] + [InlineData(200000121, "doscientos millones ciento veintiuna")] + [InlineData(1000001, "un millón una")] + public void ToWords(int number, string expected) + { + Assert.Equal(expected, number.ToWords(GrammaticalGender.Feminine)); + } + + } +} diff --git a/src/Humanizer/Localisation/NumberToWords/SpanishNumberToWordsConverter.cs b/src/Humanizer/Localisation/NumberToWords/SpanishNumberToWordsConverter.cs index d8ef2d238..97a308a5e 100644 --- a/src/Humanizer/Localisation/NumberToWords/SpanishNumberToWordsConverter.cs +++ b/src/Humanizer/Localisation/NumberToWords/SpanishNumberToWordsConverter.cs @@ -8,8 +8,11 @@ internal class SpanishNumberToWordsConverter : GenderedNumberToWordsConverter private static readonly string[] UnitsMap = { "cero", "uno", "dos", "tres", "cuatro", "cinco", "seis", "siete", "ocho", "nueve", "diez", "once", "doce", "trece", "catorce", "quince", "dieciséis", "diecisiete", "dieciocho", "diecinueve", "veinte", "veintiuno", "veintidós", "veintitrés", "veinticuatro", "veinticinco", "veintiséis", "veintisiete", "veintiocho", "veintinueve"}; + private const string Feminine1 = "una"; + private const string Feminine21 = "veintiuna"; private static readonly string[] TensMap = { "cero", "diez", "veinte", "treinta", "cuarenta", "cincuenta", "sesenta", "setenta", "ochenta", "noventa" }; private static readonly string[] HundredsMap = { "cero", "ciento", "doscientos", "trescientos", "cuatrocientos", "quinientos", "seiscientos", "setecientos", "ochocientos", "novecientos" }; + private static readonly string[] FeminineHundredsMap = { "cero", "ciento", "doscientas", "trescientas", "cuatrocientas", "quinientas", "seiscientas", "setecientas", "ochocientas", "novecientas" }; private static readonly Dictionary Ordinals = new Dictionary { @@ -38,7 +41,7 @@ public override string Convert(int number, GrammaticalGender gender) if ((number / 1000000000) > 0) { parts.Add(number / 1000000000 == 1 - ? string.Format("mil millones") + ? "mil millones" : string.Format("{0} mil millones", Convert(number / 1000000000))); number %= 1000000000; @@ -47,7 +50,7 @@ public override string Convert(int number, GrammaticalGender gender) if ((number / 1000000) > 0) { parts.Add(number / 1000000 == 1 - ? string.Format("un millón") + ? "un millón" : string.Format("{0} millones", Convert(number / 1000000))); number %= 1000000; @@ -56,34 +59,47 @@ public override string Convert(int number, GrammaticalGender gender) if ((number / 1000) > 0) { parts.Add(number / 1000 == 1 - ? string.Format("mil") - : string.Format("{0} mil", Convert(number / 1000))); + ? "mil" + : string.Format("{0} mil", Convert(number / 1000, gender))); number %= 1000; } if ((number / 100) > 0) { - parts.Add(number == 100 ? string.Format("cien") : HundredsMap[(number / 100)]); + parts.Add(number == 100 + ? "cien" + : gender == GrammaticalGender.Feminine + ? FeminineHundredsMap[(number / 100)] + : HundredsMap[(number / 100)]); number %= 100; } if (number > 0) { if (number < 30) - parts.Add(UnitsMap[number]); - else if (number > 20 && number < 30) { - var lastPart = TensMap[number / 10]; - if ((number % 10) > 0) - lastPart += string.Format(" {0}", UnitsMap[number % 10]); - - parts.Add(lastPart); + { + if (gender == GrammaticalGender.Feminine && (number == 1 || number == 21)) + { + parts.Add(number == 1 ? Feminine1 : Feminine21); + } + else + { + parts.Add(UnitsMap[number]); + } } else { - var lastPart = TensMap[number / 10]; - if ((number % 10) > 0) + var lastPart = TensMap[number/10]; + int units = number%10; + if (units == 1 && gender == GrammaticalGender.Feminine) + { + lastPart += " y una"; + } + else if (units > 0) + { lastPart += string.Format(" y {0}", UnitsMap[number % 10]); + } parts.Add(lastPart); }