diff --git a/src/Humanizer.Tests/Humanizer.Tests.csproj b/src/Humanizer.Tests/Humanizer.Tests.csproj index aaa08543a..bc0b22120 100644 --- a/src/Humanizer.Tests/Humanizer.Tests.csproj +++ b/src/Humanizer.Tests/Humanizer.Tests.csproj @@ -71,6 +71,7 @@ + diff --git a/src/Humanizer.Tests/Localisation/ar/DateHumanizeTests.cs b/src/Humanizer.Tests/Localisation/ar/DateHumanizeTests.cs new file mode 100644 index 000000000..e5670ea82 --- /dev/null +++ b/src/Humanizer.Tests/Localisation/ar/DateHumanizeTests.cs @@ -0,0 +1,78 @@ +using System; +using Xunit; +using Xunit.Extensions; + +namespace Humanizer.Tests.Localisation.ar +{ + public class DateHumanizeTests : AmbientCulture + { + public DateHumanizeTests() : base("ar") { } + + + [Theory] + [InlineData(-1, "أمس")] + [InlineData(-2, "منذ يومين")] + [InlineData(-3, "منذ 3 أيام")] + [InlineData(-11, "منذ 11 يوم")] + public void DaysAgo(int days, string expected) + { + Assert.Equal(expected, DateTime.UtcNow.AddDays(days).Humanize()); + } + + [Theory] + [InlineData(-2, "منذ ساعتين")] + [InlineData(-1, "منذ ساعة واحدة")] + [InlineData(-3, "منذ 3 ساعات")] + [InlineData(-11, "منذ 11 ساعة")] + public void HoursAgo(int hours, string expected) + { + Assert.Equal(expected, DateTime.UtcNow.AddHours(hours).Humanize()); + } + + [Theory] + [InlineData(-2, "منذ دقيقتين")] + [InlineData(-1, "منذ دقيقة واحدة")] + [InlineData(-3, "منذ 3 دقائق")] + [InlineData(-11, "منذ 11 دقيقة")] + public void MinutesAgo(int minutes, string expected) + { + Assert.Equal(expected, DateTime.UtcNow.AddMinutes(minutes).Humanize()); + } + + [Theory] + [InlineData(-2, "منذ شهرين")] + [InlineData(-1, "منذ شهر واحد")] + [InlineData(-3, "منذ 3 أشهر")] + [InlineData(-11, "منذ 11 شهر")] + public void MonthsAgo(int months, string expected) + { + Assert.Equal(expected, DateTime.UtcNow.AddMonths(months).Humanize()); + } + + [Theory] + [InlineData(-2, "منذ ثانيتين")] + [InlineData(-1, "منذ ثانية واحدة")] + [InlineData(-3, "منذ 3 ثوان")] + [InlineData(-11, "منذ 11 ثانية")] + public void SecondsAgo(int seconds, string expected) + { + Assert.Equal(expected, DateTime.UtcNow.AddSeconds(seconds).Humanize()); + } + + [Theory] + [InlineData(-2, "منذ عامين")] + [InlineData(-1, "العام السابق")] + [InlineData(-3, "منذ 3 أعوام")] + [InlineData(-11, "منذ 11 عام")] + public void YearsAgo(int years, string expected) + { + Assert.Equal(expected, DateTime.UtcNow.AddYears(years).Humanize()); + } + + [Fact] + public void NotYet() + { + Assert.Equal("ليس بعد", DateTime.UtcNow.AddDays(1).Humanize()); + } + } +} diff --git a/src/Humanizer.Tests/Localisation/ar/TimeSpanTests.cs b/src/Humanizer.Tests/Localisation/ar/TimeSpanTests.cs index f86fbb301..a4b73fd1f 100644 --- a/src/Humanizer.Tests/Localisation/ar/TimeSpanTests.cs +++ b/src/Humanizer.Tests/Localisation/ar/TimeSpanTests.cs @@ -1,5 +1,6 @@ using System; using Xunit; +using Xunit.Extensions; namespace Humanizer.Tests.Localisation.ar { @@ -7,40 +8,65 @@ public class TimeSpanHumanizeExtensionsTests : AmbientCulture { public TimeSpanHumanizeExtensionsTests() : base("ar") { } - [Fact] - public void OneWeek() + [Theory] + [InlineData(7, "أسبوع واحد")] + [InlineData(14, "أسبوعين")] + [InlineData(21, "3 أسابيع")] + [InlineData(77, "11 أسبوع")] + public void Weeks(int days, string expected) { - Assert.Equal("أسبوع واحد", TimeSpan.FromDays(7).Humanize()); + Assert.Equal(expected, TimeSpan.FromDays(days).Humanize()); } - [Fact] - public void OneDay() + + [Theory] + [InlineData(1, "يوم واحد")] + [InlineData(2, "يومين")] + [InlineData(3, "3 أيام")] + public void Days(int days, string expected) { - Assert.Equal("يوم واحد", TimeSpan.FromDays(1).Humanize()); + Assert.Equal(expected, TimeSpan.FromDays(days).Humanize()); } - [Fact] - public void OneHour() + [Theory] + [InlineData(1, "ساعة واحدة")] + [InlineData(2, "ساعتين")] + [InlineData(3, "3 ساعات")] + [InlineData(11, "11 ساعة")] + public void Hours(int hours, string expected) { - Assert.Equal("ساعة واحدة", TimeSpan.FromHours(1).Humanize()); + Assert.Equal(expected, TimeSpan.FromHours(hours).Humanize()); } - [Fact] - public void OneMinute() + [Theory] + [InlineData(1, "دقيقة واحدة")] + [InlineData(2, "دقيقتين")] + [InlineData(3, "3 دقائق")] + [InlineData(11, "11 دقيقة")] + public void Minutes(int minutes, string expected) { - Assert.Equal("دقيقة واحدة", TimeSpan.FromMinutes(1).Humanize()); + Assert.Equal(expected, TimeSpan.FromMinutes(minutes).Humanize()); } - [Fact] - public void OneSecond() + + [Theory] + [InlineData(1, "ثانية واحدة")] + [InlineData(2, "ثانيتين")] + [InlineData(3, "3 ثوان")] + [InlineData(11, "11 ثانية")] + public void Seconds(int seconds, string expected) { - Assert.Equal("ثانية واحدة", TimeSpan.FromSeconds(1).Humanize()); + Assert.Equal(expected, TimeSpan.FromSeconds(seconds).Humanize()); } - [Fact] - public void OneMillisecond() + [Theory] + [InlineData(1, "جزء من الثانية")] + [InlineData(2, "جزئين من الثانية")] + [InlineData(3, "3 أجزاء من الثانية")] + [InlineData(11, "11 جزء من الثانية")] + public void Milliseconds(int milliseconds, string expected) { - Assert.Equal("جزء من الثانية", TimeSpan.FromMilliseconds(1).Humanize()); + Assert.Equal(expected, TimeSpan.FromMilliseconds(milliseconds).Humanize()); } [Fact] diff --git a/src/Humanizer/Configuration/Configurator.cs b/src/Humanizer/Configuration/Configurator.cs index aa3a838d2..463f8e889 100644 --- a/src/Humanizer/Configuration/Configurator.cs +++ b/src/Humanizer/Configuration/Configurator.cs @@ -14,7 +14,8 @@ public static class Configurator new Dictionary>(StringComparer.OrdinalIgnoreCase) { { "ro", () => new RomanianFormatter() }, - { "ru", () => new RussianFormatter() } + { "ru", () => new RussianFormatter() }, + { "ar", () => new ArabicFormatter() }, }; /// diff --git a/src/Humanizer/Humanizer.csproj b/src/Humanizer/Humanizer.csproj index e62b5864e..96decf244 100644 --- a/src/Humanizer/Humanizer.csproj +++ b/src/Humanizer/Humanizer.csproj @@ -82,6 +82,7 @@ True On.Days.tt + diff --git a/src/Humanizer/Localisation/ArabicFormatter.cs b/src/Humanizer/Localisation/ArabicFormatter.cs new file mode 100644 index 000000000..44081c622 --- /dev/null +++ b/src/Humanizer/Localisation/ArabicFormatter.cs @@ -0,0 +1,21 @@ +namespace Humanizer.Localisation +{ + internal class ArabicFormatter : DefaultFormatter + { + private const string DualPostfix = "_Dual"; + private const string PluralPostfix = "_Plural"; + + protected override string GetResourceKey(string resourceKey, int number) + { + //In Arabic pluralization 2 entities gets a different word. + if (number == 2) + return resourceKey + DualPostfix; + + //In Arabic pluralization entities where the count is between 3 and 10 gets a different word. + if (number >= 3 && number <= 10 ) + return resourceKey + PluralPostfix; + + return resourceKey; + } + } +} diff --git a/src/Humanizer/Properties/Resources.ar.resx b/src/Humanizer/Properties/Resources.ar.resx index b0ffcc3dc..8a69e9931 100644 --- a/src/Humanizer/Properties/Resources.ar.resx +++ b/src/Humanizer/Properties/Resources.ar.resx @@ -126,7 +126,7 @@ one second ago - منذ {0} ثوان + منذ {0} ثانية {0} seconds ago @@ -134,7 +134,7 @@ a minute ago - منذ {0} دقائق + منذ {0} دقيقة {0} minutes ago @@ -142,7 +142,7 @@ an hour ago - منذ {0} ساعات + منذ {0} ساعة {0} hours ago @@ -150,7 +150,7 @@ yesterday - منذ {0} أيام + منذ {0} يوم {0} days ago @@ -158,7 +158,7 @@ one month ago - منذ {0} أشهر + منذ {0} شهر {0} months ago @@ -166,7 +166,7 @@ one year ago - منذ {0} سنوات + منذ {0} عام {0} years ago @@ -197,4 +197,124 @@ حالاً no time + + منذ يومين + two days ago + + + منذ ساعتين + two hours ago + + + منذ دقيقتين + two minutes ago + + + منذ شهرين + two months ago + + + منذ ثانيتين + two seconds ago + + + منذ عامين + two years ago + + + أسبوعين + two weeks + + + يومين + two days + + + ساعتين + two hours + + + جزئين من الثانية + two milliseconds + + + دقيقتين + two minutes + + + ثانيتين + two seconds + + + {0} يوم + {0} days + + + {0} أيام + {0} days + + + {0} ساعة + {0} hours + + + {0} ساعات + {0} hours + + + {0} جزء من الثانية + {0} milliseconds + + + {0} أجزاء من الثانية + {0} milliseconds + + + {0} دقيقة + {0} minutes + + + {0} دقائق + {0} minutes + + + {0} ثانية + {0} seconds + + + {0} ثوان + {0} seconds + + + {0} أسبوع + {0} weeks + + + {0} أسابيع + {0} weeks + + + منذ {0} أيام + {0} days ago + + + منذ {0} ساعات + {0} hours ago + + + منذ {0} دقائق + {0} minutes ago + + + منذ {0} أشهر + {0} months ago + + + منذ {0} ثوان + {0} seconds ago + + + منذ {0} أعوام + {0} years ago + \ No newline at end of file