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

Added Farsi support to DateTime resource files and NumberToWords. #121

Closed
wants to merge 8 commits into from
Closed
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
6 changes: 6 additions & 0 deletions release_notes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
###v1.16.1 - 2014-04-03
- [#121] (https://github.com/MehdiK/Humanizer/pull/121) : Added Farsi support to DateTime and NumberToWords
Copy link
Member

Choose a reason for hiding this comment

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

We still don't know what version this is going to or when this is going to be released. So new features should be added under 'In Development'

- Added Farsi support to ToQuantityExtensions

[Commits](https://github.com/MehdiK/Humanizer/compare/v1.15.1...v1.16.1)

###In Development
- [#120](https://github.com/MehdiK/Humanizer/pull/120): Added translation for culture 'de'

Expand Down
4 changes: 4 additions & 0 deletions src/Humanizer.Tests/Humanizer.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@
<Compile Include="Localisation\de\TimeSpanHumanizeTests.cs" />
<Compile Include="Localisation\es\DateHumanizeTests.cs" />
<Compile Include="Localisation\es\TimeSpanHumanizeTests.cs" />
<Compile Include="Localisation\fa\DateHumanizeTests.cs" />
<Compile Include="Localisation\fa\NumberToWordsTests.cs" />
<Compile Include="Localisation\fa\TimeSpanHumanizeTests.cs" />
<Compile Include="Localisation\fa\ToQuantityTests.cs" />
<Compile Include="Localisation\nl\DateHumanizeTests.cs" />
<Compile Include="Localisation\nl\TimeSpanHumanizeTests.cs" />
<Compile Include="Localisation\pt-BR\DateHumanizeTests.cs" />
Expand Down
72 changes: 72 additions & 0 deletions src/Humanizer.Tests/Localisation/fa/DateHumanizeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System;
using Xunit;
using Xunit.Extensions;

namespace Humanizer.Tests.Localisation.fa
{
public class DateHumanizeTests : AmbientCulture
{
public DateHumanizeTests() : base("fa") { }


[Theory]
[InlineData(1, "فردا")]
[InlineData(13, "13 روز بعد")]
[InlineData(-1, "دیروز")]
[InlineData(-11, "11 روز پیش")]
public void DaysAgo(int days, string expected)
Copy link
Member

Choose a reason for hiding this comment

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

We should either rename DaysAgo to Days or create a DaysFromNow and move the future dates there. I prefer the latter for consistency's sake.

Copy link
Member

Choose a reason for hiding this comment

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

This applies to all tests in this class

{
Assert.Equal(expected, DateTime.UtcNow.AddDays(days).Humanize());
}

[Theory]
[InlineData(1, "یک ساعت بعد")]
[InlineData(11, "11 ساعت بعد")]
[InlineData(-1, "یک ساعت پیش")]
[InlineData(-11, "11 ساعت پیش")]
public void HoursAgo(int hours, string expected)
{
Assert.Equal(expected, DateTime.UtcNow.AddHours(hours).Humanize());
}

[Theory]
[InlineData(1, "یک دقیقه بعد")]
[InlineData(13, "13 دقیقه بعد")]
[InlineData(-1, "یک دقیقه پیش")]
[InlineData(-13, "13 دقیقه پیش")]
public void MinutesAgo(int minutes, string expected)
{
Assert.Equal(expected, DateTime.UtcNow.AddMinutes(minutes).Humanize());
}

[Theory]
[InlineData(1, "یک ماه بعد")]
[InlineData(10, "10 ماه بعد")]
[InlineData(-1, "یک ماه پیش")]
[InlineData(-10, "10 ماه پیش")]
public void MonthsAgo(int months, string expected)
{
Assert.Equal(expected, DateTime.UtcNow.AddMonths(months).Humanize());
}

[Theory]
[InlineData(1, "یک ثانیه بعد")]
[InlineData(11, "11 ثانیه بعد")]
[InlineData(-1, "یک ثانیه پیش")]
[InlineData(-11, "11 ثانیه پیش")]
public void SecondsAgo(int seconds, string expected)
{
Assert.Equal(expected, DateTime.UtcNow.AddSeconds(seconds).Humanize());
}

[Theory]
[InlineData(1, "یک سال بعد")]
[InlineData(21, "21 سال بعد")]
[InlineData(-1, "یک سال پیش")]
[InlineData(-21, "21 سال پیش")]
public void YearsAgo(int years, string expected)
{
Assert.Equal(expected, DateTime.UtcNow.AddYears(years).Humanize());
}
}
}
43 changes: 43 additions & 0 deletions src/Humanizer.Tests/Localisation/fa/NumberToWordsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Xunit;
using Xunit.Extensions;

namespace Humanizer.Tests.Localisation.fa
{
public class NumberToWordsTests : AmbientCulture
{
public NumberToWordsTests() : base("fa") { }

[InlineData(1, "یک")]
[InlineData(10, "ده")]
[InlineData(11, "یازده")]
[InlineData(122, "صد و بیست و دو")]
[InlineData(3501, "سه هزار و پانصد و یک")]
[InlineData(100, "صد")]
[InlineData(1000, "یک هزار")]
[InlineData(100000, "صد هزار")]
[InlineData(1000000, "یک میلیون")]
[InlineData(10000000, "ده میلیون")]
[InlineData(100000000, "صد میلیون")]
[InlineData(1000000000, "یک میلیارد")]
[InlineData(111, "صد و یازده")]
[InlineData(1111, "یک هزار و صد و یازده")]
[InlineData(111111, "صد و یازده هزار و صد و یازده")]
[InlineData(1111111, "یک میلیون و صد و یازده هزار و صد و یازده")]
[InlineData(11111111, "یازده میلیون و صد و یازده هزار و صد و یازده")]
[InlineData(111111111, "صد و یازده میلیون و صد و یازده هزار و صد و یازده")]
[InlineData(1111111111, "یک میلیارد و صد و یازده میلیون و صد و یازده هزار و صد و یازده")]
[InlineData(123, "صد و بیست و سه")]
[InlineData(1234, "یک هزار و دویست و سی و چهار")]
[InlineData(12345, "دوازده هزار و سیصد و چهل و پنج")]
[InlineData(123456, "صد و بیست و سه هزار و چهارصد و پنجاه و شش")]
[InlineData(1234567, "یک میلیون و دویست و سی و چهار هزار و پانصد و شصت و هفت")]
[InlineData(12345678, "دوازده میلیون و سیصد و چهل و پنج هزار و ششصد و هفتاد و هشت")]
[InlineData(123456789, "صد و بیست و سه میلیون و چهارصد و پنجاه و شش هزار و هفتصد و هشتاد و نه")]
[InlineData(1234567890, "یک میلیارد و دویست و سی و چهار میلیون و پانصد و شصت و هفت هزار و هشتصد و نود")]
[Theory]
Copy link
Member

Choose a reason for hiding this comment

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

Please move the Theory attr to the top for consistency.

public void ToWordsFarsi(int number, string expected)
{
Assert.Equal(expected, number.ToWords());
}
}
}
67 changes: 67 additions & 0 deletions src/Humanizer.Tests/Localisation/fa/TimeSpanHumanizeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System;
using Xunit;
using Xunit.Extensions;

namespace Humanizer.Tests.Localisation.fa
{
public class TimeSpanHumanizeTests : AmbientCulture
{
public TimeSpanHumanizeTests() : base("fa") { }

[Theory]
[InlineData(7, "یک هفته")]
[InlineData(77, "11 هفته")]
public void Weeks(int days, string expected)
{
Assert.Equal(expected, TimeSpan.FromDays(days).Humanize());
}

Copy link
Member

Choose a reason for hiding this comment

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

Please remove the redundant line breaks.


[Theory]
[InlineData(1, "یک روز")]
[InlineData(3, "3 روز")]
public void Days(int days, string expected)
{
Assert.Equal(expected, TimeSpan.FromDays(days).Humanize());
}

[Theory]
[InlineData(1, "یک ساعت")]
[InlineData(11, "11 ساعت")]
public void Hours(int hours, string expected)
{
Assert.Equal(expected, TimeSpan.FromHours(hours).Humanize());
}

[Theory]
[InlineData(1, "یک دقیقه")]
[InlineData(11, "11 دقیقه")]
public void Minutes(int minutes, string expected)
{
Assert.Equal(expected, TimeSpan.FromMinutes(minutes).Humanize());
}


[Theory]
[InlineData(1, "یک ثانیه")]
[InlineData(11, "11 ثانیه")]
public void Seconds(int seconds, string expected)
{
Assert.Equal(expected, TimeSpan.FromSeconds(seconds).Humanize());
}

[Theory]
[InlineData(1, "یک میلی ثانیه")]
[InlineData(11, "11 میلی ثانیه")]
public void Milliseconds(int milliseconds, string expected)
{
Assert.Equal(expected, TimeSpan.FromMilliseconds(milliseconds).Humanize());
}

[Fact]
public void NoTime()
{
Assert.Equal("الآن", TimeSpan.Zero.Humanize());
}
}
}
48 changes: 48 additions & 0 deletions src/Humanizer.Tests/Localisation/fa/ToQuantityTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Xunit;
using Xunit.Extensions;

namespace Humanizer.Tests.Localisation.fa
{
public class ToQuantityTests : AmbientCulture
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 the first localisation done on ToQuantity. Exciting times! However, this doesn't fit into this PR. Please create a separate PR for ToQuantity. We have to discuss and review this more thoroughly. So I'll skip over the whole ToQuantity bit.

{
public ToQuantityTests()
: base("fa") { }

[Theory]
[InlineData("مرد", 0, "0 مرد")]
[InlineData("مرد", 1, "1 مرد")]
[InlineData("مرد", 5, "5 مرد")]
public void ToQuantity(string word, int quatity, string expected)
{
Assert.Equal(expected, word.ToQuantity(quatity));
}

[Theory]
[InlineData("مرد", 0, "مرد")]
[InlineData("مرد", 1, "مرد")]
[InlineData("مرد", 5, "مرد ها")]
public void ToQuantityWithNoQuantity(string word, int quatity, string expected)
{
Assert.Equal(expected, word.ToQuantity(quatity, ShowQuantityAs.None));
}

[Theory]
[InlineData("مرد", 0, "0 مرد")]
[InlineData("مرد", 1, "1 مرد")]
[InlineData("مرد", 5, "5 مرد")]
public void ToQuantityNumeric(string word, int quatity, string expected)
{
// ReSharper disable once RedundantArgumentDefaultValue
Assert.Equal(expected, word.ToQuantity(quatity, ShowQuantityAs.Numeric));
}

[Theory]
[InlineData("مرد", 2, "دو مرد")]
[InlineData("مرد", 1, "یک مرد")]
[InlineData("مرد", 1200, "یک هزار و دویست مرد")]
public void ToQuantityWords(string word, int quatity, string expected)
{
Assert.Equal(expected, word.ToQuantity(quatity, ShowQuantityAs.Words));
}
}
}
9 changes: 9 additions & 0 deletions src/Humanizer/Configuration/Configurator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Globalization;
using Humanizer.Localisation;
using Humanizer.Localisation.Quantifier;

namespace Humanizer.Configuration
{
Expand Down Expand Up @@ -33,5 +34,13 @@ public static IFormatter Formatter
return new DefaultFormatter();
}
}

internal static IQuantifier Quantifier
{
get
{
return QuantifierFactory.GetQuantifier();
}
}
}
}
5 changes: 5 additions & 0 deletions src/Humanizer/Humanizer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@
<Compile Include="CasingExtensions.cs" />
<Compile Include="Configuration\Configurator.cs" />
<Compile Include="DateHumanizeExtensions.cs" />
<Compile Include="Localisation\Quantifier\DefaultQuantifier.cs" />
<Compile Include="Localisation\Quantifier\FarsiQuantifier.cs" />
<Compile Include="Localisation\Quantifier\IQuantifier.cs" />
<Compile Include="Localisation\Quantifier\QuantifierFactory.cs" />
<Compile Include="Localisation\TimeUnitTense.cs" />
<Compile Include="TimeSpanHumanizeExtensions.cs" />
<Compile Include="FluentDate\In.SomeTimeFrom.cs">
Expand Down Expand Up @@ -150,6 +154,7 @@
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.de.resx" />
<EmbeddedResource Include="Properties\Resources.fa.resx" />
<EmbeddedResource Include="Properties\Resources.nb-NO.resx" />
<EmbeddedResource Include="Properties\Resources.af.resx" />
<EmbeddedResource Include="Properties\Resources.fr-BE.resx" />
Expand Down
30 changes: 30 additions & 0 deletions src/Humanizer/Localisation/Quantifier/DefaultQuantifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Humanizer.Localisation.Quantifier
{
internal class DefaultQuantifier : IQuantifier
{
public string ToQuantity(string input, int quantity, ShowQuantityAs showQuantityAs)
{
var transformedInput = TransformInput(input, quantity, showQuantityAs);

if (showQuantityAs == ShowQuantityAs.None)
return transformedInput;

if (showQuantityAs == ShowQuantityAs.Numeric)
return string.Format("{0} {1}", quantity, transformedInput);

return string.Format("{0} {1}", quantity.ToWords(), transformedInput);
}

protected virtual string TransformInput(string input, int quantity, ShowQuantityAs showQuantityAs)
{
return quantity == 1
? input.Singularize(Plurality.CouldBeEither)
: input.Pluralize(Plurality.CouldBeEither);
}
}
}
23 changes: 23 additions & 0 deletions src/Humanizer/Localisation/Quantifier/FarsiQuantifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Humanizer.Localisation.Quantifier
{
internal class FarsiQuantifier : DefaultQuantifier
{
protected override string TransformInput(string input, int quantity, ShowQuantityAs showQuantityAs)
{
//TODO: Use singularize and pluralize for Farsi
string postFix = string.Empty;

if (showQuantityAs == ShowQuantityAs.None && quantity > 1)
{
postFix = " ها";
}

return string.Format("{0}{1}", input, postFix);
}
}
}
12 changes: 12 additions & 0 deletions src/Humanizer/Localisation/Quantifier/IQuantifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Humanizer.Localisation.Quantifier
{
interface IQuantifier
{
string ToQuantity(string input, int quantity, ShowQuantityAs showQuantityAs);
}
}
34 changes: 34 additions & 0 deletions src/Humanizer/Localisation/Quantifier/QuantifierFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;

namespace Humanizer.Localisation.Quantifier
{
internal class QuantifierFactory
{
internal static IQuantifier GetQuantifier(CultureInfo culture)
{
return GetQuantifier(culture.TwoLetterISOLanguageName);
}

internal static IQuantifier GetQuantifier()
{
return GetQuantifier(Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName);
}

private static IQuantifier GetQuantifier(string twoLetterISOLanguageName)
{
switch (twoLetterISOLanguageName)
{
case "fa":
return new FarsiQuantifier();
default:
return new DefaultQuantifier();
}
}

}
}
Loading