Skip to content
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 German localisation for ToOrdinalWords and Ordinalize #257

Merged
merged 4 commits into from
May 3, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions release_notes.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
###In Development
- [#257](https://github.com/Mehdik/Humanizer/pull/257): Added German localisation for ToOrdinalWords and Ordinalize

[Commits](https://github.com/MehdiK/Humanizer/compare/v1.25.4...master)

Expand Down
1 change: 1 addition & 0 deletions src/Humanizer.Tests/Humanizer.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
<Compile Include="Localisation\da\DateHumanizeTests.cs" />
<Compile Include="Localisation\da\TimeSpanHumanizeTests.cs" />
<Compile Include="Localisation\de\NumberToWordsTests.cs" />
<Compile Include="Localisation\de\OrdinalizeTests.cs" />
<Compile Include="Localisation\es\OrdinalizeTests.cs" />
<Compile Include="Localisation\fr-BE\DateHumanizeTests.cs" />
<Compile Include="Localisation\fr-BE\TimeSpanHumanizeTests.cs" />
Expand Down
98 changes: 98 additions & 0 deletions src/Humanizer.Tests/Localisation/de/NumberToWordsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,103 @@ public void ToWords(int number, string expected)
{
Assert.Equal(expected, number.ToWords());
}

[Theory]
[InlineData(0, "nullter")]
[InlineData(1, "erster")]
[InlineData(2, "zweiter")]
[InlineData(3, "dritter")]
[InlineData(4, "vierter")]
[InlineData(5, "fünfter")]
[InlineData(6, "sechster")]
[InlineData(7, "siebter")]
[InlineData(8, "achter")]
[InlineData(9, "neunter")]
[InlineData(10, "zehnter")]
[InlineData(20, "zwanzigster")]
[InlineData(30, "dreißigster")]
[InlineData(40, "vierzigster")]
[InlineData(50, "fünfzigster")]
[InlineData(60, "sechzigster")]
[InlineData(70, "siebzigster")]
[InlineData(80, "achtzigster")]
[InlineData(90, "neunzigster")]
[InlineData(100, "einhundertster")]
[InlineData(200, "zweihundertster")]
[InlineData(1000, "eintausendster")]
[InlineData(10000, "zehntausendster")]
[InlineData(100000, "einhunderttausendster")]
[InlineData(1000000, "einmillionster")]
[InlineData(10000000, "zehnmillionster")]
[InlineData(100000000, "einhundertmillionster")]
[InlineData(1000000000, "einmilliardster")]
[InlineData(2000000000, "zweimilliardster")]
[InlineData(122, "einhundertzweiundzwanzigster")]
[InlineData(3501, "dreitausendfünfhunderterster")]
[InlineData(111, "einhundertelfter")]
[InlineData(1112, "eintausendeinhundertzwölfter")]
[InlineData(11213, "elftausendzweihundertdreizehnter")]
[InlineData(121314, "einhunderteinundzwanzigtausenddreihundertvierzehnter")]
[InlineData(2132415, "zweimillioneneinhundertzweiunddreißigtausendvierhundertfünfzehnter")]
[InlineData(12345516, "zwölfmillionendreihundertfünfundvierzigtausendfünfhundertsechzehnter")]
[InlineData(751633617, "siebenhunderteinundfünfzigmillionensechshundertdreiunddreißigtausendsechshundertsiebzehnter")]
[InlineData(1111111118, "einemilliardeeinhundertelfmillioneneinhundertelftausendeinhundertachtzehnter")]
[InlineData(-751633619, "minus siebenhunderteinundfünfzigmillionensechshundertdreiunddreißigtausendsechshundertneunzehnter")]
public void ToOrdinalWords(int number, string expected)
{
Assert.Equal(expected, number.ToOrdinalWords());
}

[Theory]
[InlineData(0, "nullte")]
[InlineData(1, "erste")]
[InlineData(2, "zweite")]
[InlineData(3, "dritte")]
[InlineData(4, "vierte")]
[InlineData(5, "fünfte")]
[InlineData(6, "sechste")]
[InlineData(7, "siebte")]
[InlineData(8, "achte")]
[InlineData(9, "neunte")]
[InlineData(10, "zehnte")]
[InlineData(111, "einhundertelfte")]
[InlineData(1112, "eintausendeinhundertzwölfte")]
[InlineData(11213, "elftausendzweihundertdreizehnte")]
[InlineData(121314, "einhunderteinundzwanzigtausenddreihundertvierzehnte")]
[InlineData(2132415, "zweimillioneneinhundertzweiunddreißigtausendvierhundertfünfzehnte")]
[InlineData(12345516, "zwölfmillionendreihundertfünfundvierzigtausendfünfhundertsechzehnte")]
[InlineData(751633617, "siebenhunderteinundfünfzigmillionensechshundertdreiunddreißigtausendsechshundertsiebzehnte")]
[InlineData(1111111118, "einemilliardeeinhundertelfmillioneneinhundertelftausendeinhundertachtzehnte")]
[InlineData(-751633619, "minus siebenhunderteinundfünfzigmillionensechshundertdreiunddreißigtausendsechshundertneunzehnte")]
public void ToOrdinalWordsFeminine(int number, string expected)
{
Assert.Equal(expected, number.ToOrdinalWords(GrammaticalGender.Feminine));
}

[Theory]
[InlineData(0, "nulltes")]
[InlineData(1, "erstes")]
[InlineData(2, "zweites")]
[InlineData(3, "drittes")]
[InlineData(4, "viertes")]
[InlineData(5, "fünftes")]
[InlineData(6, "sechstes")]
[InlineData(7, "siebtes")]
[InlineData(8, "achtes")]
[InlineData(9, "neuntes")]
[InlineData(10, "zehntes")]
[InlineData(111, "einhundertelftes")]
[InlineData(1112, "eintausendeinhundertzwölftes")]
[InlineData(11213, "elftausendzweihundertdreizehntes")]
[InlineData(121314, "einhunderteinundzwanzigtausenddreihundertvierzehntes")]
[InlineData(2132415, "zweimillioneneinhundertzweiunddreißigtausendvierhundertfünfzehntes")]
[InlineData(12345516, "zwölfmillionendreihundertfünfundvierzigtausendfünfhundertsechzehntes")]
[InlineData(751633617, "siebenhunderteinundfünfzigmillionensechshundertdreiunddreißigtausendsechshundertsiebzehntes")]
[InlineData(1111111118, "einemilliardeeinhundertelfmillioneneinhundertelftausendeinhundertachtzehntes")]
[InlineData(-751633619, "minus siebenhunderteinundfünfzigmillionensechshundertdreiunddreißigtausendsechshundertneunzehntes")]
public void ToOrdinalWordsNeuter(int number, string expected)
{
Assert.Equal(expected, number.ToOrdinalWords(GrammaticalGender.Neuter));
}
}
}
29 changes: 29 additions & 0 deletions src/Humanizer.Tests/Localisation/de/OrdinalizeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Xunit;
using Xunit.Extensions;

namespace Humanizer.Tests.Localisation.de
{
public class OrdinalizeTests : AmbientCulture
{
public OrdinalizeTests() : base("de-DE") { }

[Theory]
[InlineData("0", "0.")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a strange rule!

[InlineData("1", "1.")]
[InlineData("2", "2.")]
[InlineData("3", "3.")]
[InlineData("4", "4.")]
[InlineData("5", "5.")]
[InlineData("6", "6.")]
[InlineData("23", "23.")]
[InlineData("100", "100.")]
[InlineData("101", "101.")]
[InlineData("102", "102.")]
[InlineData("103", "103.")]
[InlineData("1001", "1001.")]
public void OrdinalizeString(string number, string ordinalized)
{
Assert.Equal(number.Ordinalize(), ordinalized);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first argument in xUnit assertion is expected value. No worries. I will fix this as part of merge.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, ok thanks.

}
}
}
1 change: 1 addition & 0 deletions src/Humanizer/Configuration/OrdinalizerRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public OrdinalizerRegistry() : base(new DefaultOrdinalizer())
Register<SpanishOrdinalizer>("es");
Register<RussianOrdinalizer>("ru");
Register<BrazilianPortugueseOrdinalizer>("pt-BR");
Register<GermanOrdinalizer>("de");
}
}
}
1 change: 1 addition & 0 deletions src/Humanizer/Humanizer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
<Compile Include="Localisation\NumberToWords\RussianNumberToWordsConverter.cs" />
<Compile Include="Localisation\Formatters\HebrewFormatter.cs" />
<Compile Include="Localisation\Ordinalizers\IOrdinalizer.cs" />
<Compile Include="Localisation\Ordinalizers\GermanOrdinalizer.cs" />
<Compile Include="Localisation\Ordinalizers\RussianOrdinalizer.cs" />
<Compile Include="Localisation\Ordinalizers\SpanishOrdinalizer.cs" />
<Compile Include="Localisation\Ordinalizers\DefaultOrdinalizer.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;

namespace Humanizer.Localisation.NumberToWords
{
internal class GermanNumberToWordsConverter : DefaultNumberToWordsConverter
{
private static readonly string[] UnitsMap = { "null", "ein", "zwei", "drei", "vier", "fünf", "sechs", "sieben", "acht", "neun", "zehn", "elf", "zwölf", "dreizehn", "vierzehn", "fünfzehn", "sechzehn", "siebzehn", "achtzehn", "neunzehn" };
private static readonly string[] TensMap = { "null", "zehn", "zwanzig", "dreißig", "vierzig", "fünfzig", "sechzig", "siebzig", "achtzig", "neunzig" };
private static readonly string[] UnitsOrdinal = { string.Empty, "ers", "zwei", "drit", "vier", "fünf", "sechs", "sieb", "ach", "neun", "zehn", "elf", "zwölf", "dreizehn", "vierzehn", "fünfzehn", "sechzehn", "siebzehn", "achtzehn", "neunzehn" };
private static readonly string[] MillionOrdinalSingular = {"einmillion", "einemillion"};
private static readonly string[] MillionOrdinalPlural = {"{0}million", "{0}millionen"};
private static readonly string[] BillionOrdinalSingular = {"einmilliard", "einemilliarde"};
private static readonly string[] BillionOrdinalPlural = {"{0}milliard", "{0}milliarden"};

public override string Convert(int number)
{
Expand All @@ -17,7 +23,7 @@ public override string Convert(int number)

var parts = new List<string>();

var billions = number / 1000000000;
var billions = number/1000000000;
if (billions > 0)
{
parts.Add(Part("{0} Milliarden", "eine Milliarde", billions));
Expand All @@ -26,7 +32,7 @@ public override string Convert(int number)
parts.Add(" ");
}

var millions = number / 1000000;
var millions = number/1000000;
if (millions > 0)
{
parts.Add(Part("{0} Millionen", "eine Million", millions));
Expand All @@ -35,14 +41,14 @@ public override string Convert(int number)
parts.Add(" ");
}

var thousands = number / 1000;
var thousands = number/1000;
if (thousands > 0)
{
parts.Add(Part("{0}tausend", "eintausend", thousands));
number %= 1000;
}

var hundreds = number / 100;
var hundreds = number/100;
if (hundreds > 0)
{
parts.Add(Part("{0}hundert", "einhundert", hundreds));
Expand All @@ -60,22 +66,100 @@ public override string Convert(int number)
}
else
{
var units = number % 10;
var units = number%10;
if (units > 0)
parts.Add(string.Format("{0}und", UnitsMap[units]));

parts.Add(TensMap[number / 10]);
parts.Add(TensMap[number/10]);
}
}

return string.Join("", parts);
}

public override string ConvertToOrdinal(int number)
{
return ConvertToOrdinal(number, GrammaticalGender.Masculine);
}

public override string ConvertToOrdinal(int number, GrammaticalGender gender)
{
if (number == 0)
return "null" + GetEndingForGender(gender);

var parts = new List<string>();
if (number < 0)
{
parts.Add("minus ");
number = -number;
}

var billions = number/1000000000;
if (billions > 0)
{
number %= 1000000000;
var noRest = NoRestIndex(number);
parts.Add(Part(BillionOrdinalPlural[noRest], BillionOrdinalSingular[noRest], billions));
}

var millions = number/1000000;
if (millions > 0)
{
number %= 1000000;
var noRest = NoRestIndex(number);
parts.Add(Part(MillionOrdinalPlural[noRest], MillionOrdinalSingular[noRest], millions));
}

var thousands = number/1000;
if (thousands > 0)
{
parts.Add(Part("{0}tausend", "eintausend", thousands));
number %= 1000;
}

var hundreds = number/100;
if (hundreds > 0)
{
parts.Add(Part("{0}hundert", "einhundert", hundreds));
number %= 100;
}

if (number > 0)
parts.Add(number < 20 ? UnitsOrdinal[number] : Convert(number));

if (number == 0 || number >= 20)
parts.Add("s");

parts.Add(GetEndingForGender(gender));

return string.Join("", parts);
}

private string Part(string pluralFormat, string singular, int number)
{
if (number == 1)
return singular;
return string.Format(pluralFormat, Convert(number));
}

private static int NoRestIndex(int number)
{
return number == 0 ? 0 : 1;
}

private static string GetEndingForGender(GrammaticalGender gender)
{
switch (gender)
{
case GrammaticalGender.Masculine:
return "ter";
case GrammaticalGender.Feminine:
return "te";
case GrammaticalGender.Neuter:
return "tes";
default:
throw new ArgumentOutOfRangeException("gender");
}
}
}
}
10 changes: 10 additions & 0 deletions src/Humanizer/Localisation/Ordinalizers/GermanOrdinalizer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Humanizer.Localisation.Ordinalizers
{
internal class GermanOrdinalizer : DefaultOrdinalizer
{
public override string Convert(int number, string numberString)
{
return numberString + ".";
}
}
}