From dc82951d00bda29d7c833af0ebfbd0ea3bfc4492 Mon Sep 17 00:00:00 2001 From: brz Date: Mon, 31 Mar 2014 01:47:01 +0430 Subject: [PATCH 1/7] Added Farsi support to NumberToWordsExtension --- src/Humanizer.Tests/NumberToWordsTests.cs | 36 +++++++++++++ src/Humanizer/NumberToWordsExtension.cs | 65 +++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/src/Humanizer.Tests/NumberToWordsTests.cs b/src/Humanizer.Tests/NumberToWordsTests.cs index ea9468499..502b38c22 100644 --- a/src/Humanizer.Tests/NumberToWordsTests.cs +++ b/src/Humanizer.Tests/NumberToWordsTests.cs @@ -37,5 +37,41 @@ public void ToWords(int number, string expected) { Assert.Equal(expected, number.ToWords()); } + + + [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] + public void ToWordsFarsi(int number, string expected) + { + System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("fa-ir"); + Assert.Equal(expected, number.ToWords()); + System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture; + } } } diff --git a/src/Humanizer/NumberToWordsExtension.cs b/src/Humanizer/NumberToWordsExtension.cs index 685553f11..2cdee927d 100644 --- a/src/Humanizer/NumberToWordsExtension.cs +++ b/src/Humanizer/NumberToWordsExtension.cs @@ -20,6 +20,8 @@ public static string ToWords(this int number) { case "ar": return ToArabicWords(number); + case "fa": + return ToFarsiWords(number); default: return ToEnglishWords(number); } @@ -188,5 +190,68 @@ private static string ToArabicWords(int number) return result.Trim(); } + + private static string ToFarsiWords(int number) + { + if (number < 0) + return string.Format("منفی {0}", ToFarsiWords(-number)); + if (number == 0) + return "صفر"; + + var farsiHundredsMap = new[] + { + "صفر", + "صد", + "دویست", + "سیصد", + "چهارصد", + "پانصد", + "ششصد", + "هفتصد", + "هشتصد", + "نهصد", + }; + + + var farsiTensMap = new[] + { + "صفر", "ده","بیست","سی","چهل","پنجاه","شصت","هفتاد","هشتاد","نود" + }; + + var farsiUnitsMap = new[] + { + "صفر", "یک","دو","سه","چهار","پنج","شش","هفت","هشت","نه","ده","یازده","دوازده","سیزده","چهارده","پانزده","شانزده","هفده","هجده","نوزده" + }; + + var farsiGroupsMap = new Dictionary> { + {(int)Math.Pow(10, 9), n => string.Format("{0} میلیارد", ToFarsiWords(n)) }, + {(int)Math.Pow(10, 6), n => string.Format("{0} میلیون", ToFarsiWords(n)) }, + {(int)Math.Pow(10, 3), n => string.Format("{0} هزار", ToFarsiWords(n)) }, + {(int)Math.Pow(10, 2), n => farsiHundredsMap[n]} + }; + + var parts = new List(); + foreach (var group in farsiGroupsMap.Keys) + { + if (number / group > 0) + { + parts.Add(farsiGroupsMap[group](number / group)); + number %= group; + } + } + + if (number >= 20) + { + parts.Add(farsiTensMap[number / 10]); + number %= 10; + } + + if (number > 0) + { + parts.Add(farsiUnitsMap[number]); + } + + return string.Join(" و ", parts); + } } } From 0343fb7850cc063a7b1b64ead5e20d9e80ee143b Mon Sep 17 00:00:00 2001 From: brz Date: Wed, 2 Apr 2014 03:15:46 +0430 Subject: [PATCH 2/7] Added Farsi resource file for DateTime localization --- src/Humanizer/Humanizer.csproj | 1 + src/Humanizer/Properties/Resources.fa.resx | 234 +++++++++++++++++++++ 2 files changed, 235 insertions(+) create mode 100644 src/Humanizer/Properties/Resources.fa.resx diff --git a/src/Humanizer/Humanizer.csproj b/src/Humanizer/Humanizer.csproj index f45626c98..9c53de885 100644 --- a/src/Humanizer/Humanizer.csproj +++ b/src/Humanizer/Humanizer.csproj @@ -150,6 +150,7 @@ + diff --git a/src/Humanizer/Properties/Resources.fa.resx b/src/Humanizer/Properties/Resources.fa.resx new file mode 100644 index 000000000..813d12c04 --- /dev/null +++ b/src/Humanizer/Properties/Resources.fa.resx @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + یک ثانیه پیش + + + {0} ثانیه پیش + + + یک دقیقه پیش + + + {0} دقیقه پیش + + + یک ساعت پیش + + + {0} ساعت پیش + + + دیروز + + + {0} روز پیش + + + یک ماه پیش + + + {0} ماه پیش + + + یک سال پیش + + + {0} سال پیش + + + {0} روز + + + {0} ساعت + + + {0} میلی ثانیه + + + {0} دقیقه + + + {0} ثانیه + + + 1 روز + + + 1 ساعت + + + 1 میلی ثانیه + + + 1 دقیقه + + + 1 ثانیه + + + الان + + + {0} هفته + + + 1 هفته + + + {0} روز بعد + + + {0} ساعت بعد + + + {0} دقیقه بعد + + + {0} ماه بعد + + + {0} ثانیه بعد + + + {0} سال بعد + + + الان + + + فردا + + + یک ساعت بعد + + + یک دقیقه بعد + + + یک ماه بعد + + + یک ثانیه بعد + + + یک سال بعد + + \ No newline at end of file From 9434a53ffed41297580acd95e73b21b9553ee7e6 Mon Sep 17 00:00:00 2001 From: brz Date: Thu, 3 Apr 2014 15:35:03 +0430 Subject: [PATCH 3/7] refactored tests and updated release_notes --- release_notes.md | 5 ++ src/Humanizer.Tests/Humanizer.Tests.csproj | 3 + .../Localisation/fa/DateHumanizeTests.cs | 72 +++++++++++++++++++ .../Localisation/fa/NumberToWordsTests.cs | 43 +++++++++++ .../Localisation/fa/TimeSpanHumanizeTests.cs | 67 +++++++++++++++++ src/Humanizer.Tests/NumberToWordsTests.cs | 35 --------- src/Humanizer/NumberToWordsExtension.cs | 28 +++----- src/Humanizer/Properties/Resources.fa.resx | 16 ++--- 8 files changed, 206 insertions(+), 63 deletions(-) create mode 100644 src/Humanizer.Tests/Localisation/fa/DateHumanizeTests.cs create mode 100644 src/Humanizer.Tests/Localisation/fa/NumberToWordsTests.cs create mode 100644 src/Humanizer.Tests/Localisation/fa/TimeSpanHumanizeTests.cs diff --git a/release_notes.md b/release_notes.md index 8dc9f54f8..86150d068 100644 --- a/release_notes.md +++ b/release_notes.md @@ -1,3 +1,8 @@ +###v1.16.1 - 2014-04-03 + - [#121] (https://github.com/MehdiK/Humanizer/pull/121) : Added Farsi support to DateTime and NumberToWords + +[Commits](https://github.com/MehdiK/Humanizer/compare/v1.15.1...master) + ###In Development - [#120](https://github.com/MehdiK/Humanizer/pull/120): Added translation for culture 'de' diff --git a/src/Humanizer.Tests/Humanizer.Tests.csproj b/src/Humanizer.Tests/Humanizer.Tests.csproj index d0659af4d..240ae5aeb 100644 --- a/src/Humanizer.Tests/Humanizer.Tests.csproj +++ b/src/Humanizer.Tests/Humanizer.Tests.csproj @@ -83,6 +83,9 @@ + + + diff --git a/src/Humanizer.Tests/Localisation/fa/DateHumanizeTests.cs b/src/Humanizer.Tests/Localisation/fa/DateHumanizeTests.cs new file mode 100644 index 000000000..536e08a13 --- /dev/null +++ b/src/Humanizer.Tests/Localisation/fa/DateHumanizeTests.cs @@ -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) + { + 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()); + } + } +} diff --git a/src/Humanizer.Tests/Localisation/fa/NumberToWordsTests.cs b/src/Humanizer.Tests/Localisation/fa/NumberToWordsTests.cs new file mode 100644 index 000000000..d5730849f --- /dev/null +++ b/src/Humanizer.Tests/Localisation/fa/NumberToWordsTests.cs @@ -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] + public void ToWordsFarsi(int number, string expected) + { + Assert.Equal(expected, number.ToWords()); + } + } +} diff --git a/src/Humanizer.Tests/Localisation/fa/TimeSpanHumanizeTests.cs b/src/Humanizer.Tests/Localisation/fa/TimeSpanHumanizeTests.cs new file mode 100644 index 000000000..634535aa9 --- /dev/null +++ b/src/Humanizer.Tests/Localisation/fa/TimeSpanHumanizeTests.cs @@ -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()); + } + + + [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()); + } + } +} \ No newline at end of file diff --git a/src/Humanizer.Tests/NumberToWordsTests.cs b/src/Humanizer.Tests/NumberToWordsTests.cs index 502b38c22..16a3d98a8 100644 --- a/src/Humanizer.Tests/NumberToWordsTests.cs +++ b/src/Humanizer.Tests/NumberToWordsTests.cs @@ -38,40 +38,5 @@ public void ToWords(int number, string expected) Assert.Equal(expected, number.ToWords()); } - - [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] - public void ToWordsFarsi(int number, string expected) - { - System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("fa-ir"); - Assert.Equal(expected, number.ToWords()); - System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture; - } } } diff --git a/src/Humanizer/NumberToWordsExtension.cs b/src/Humanizer/NumberToWordsExtension.cs index 2cdee927d..5b3997d17 100644 --- a/src/Humanizer/NumberToWordsExtension.cs +++ b/src/Humanizer/NumberToWordsExtension.cs @@ -195,41 +195,29 @@ private static string ToFarsiWords(int number) { if (number < 0) return string.Format("منفی {0}", ToFarsiWords(-number)); + if (number == 0) return "صفر"; var farsiHundredsMap = new[] { - "صفر", - "صد", - "دویست", - "سیصد", - "چهارصد", - "پانصد", - "ششصد", - "هفتصد", - "هشتصد", - "نهصد", + "صفر", "صد", "دویست", "سیصد", "چهارصد", "پانصد", "ششصد", "هفتصد", "هشتصد", "نهصد" }; - - var farsiTensMap = new[] - { - "صفر", "ده","بیست","سی","چهل","پنجاه","شصت","هفتاد","هشتاد","نود" - }; - + { + "صفر", "ده", "بیست", "سی", "چهل", "پنجاه", "شصت", "هفتاد", "هشتاد", "نود" + }; var farsiUnitsMap = new[] { - "صفر", "یک","دو","سه","چهار","پنج","شش","هفت","هشت","نه","ده","یازده","دوازده","سیزده","چهارده","پانزده","شانزده","هفده","هجده","نوزده" + "صفر", "یک", "دو", "سه", "چهار", "پنج", "شش", "هفت", "هشت", "نه", "ده", "یازده", "دوازده", "سیزده", "چهارده", "پانزده", "شانزده", "هفده", "هجده", "نوزده" }; - - var farsiGroupsMap = new Dictionary> { + var farsiGroupsMap = new Dictionary> + { {(int)Math.Pow(10, 9), n => string.Format("{0} میلیارد", ToFarsiWords(n)) }, {(int)Math.Pow(10, 6), n => string.Format("{0} میلیون", ToFarsiWords(n)) }, {(int)Math.Pow(10, 3), n => string.Format("{0} هزار", ToFarsiWords(n)) }, {(int)Math.Pow(10, 2), n => farsiHundredsMap[n]} }; - var parts = new List(); foreach (var group in farsiGroupsMap.Keys) { diff --git a/src/Humanizer/Properties/Resources.fa.resx b/src/Humanizer/Properties/Resources.fa.resx index 813d12c04..412163855 100644 --- a/src/Humanizer/Properties/Resources.fa.resx +++ b/src/Humanizer/Properties/Resources.fa.resx @@ -169,28 +169,28 @@ {0} ثانیه - 1 روز + یک روز - 1 ساعت + یک ساعت - 1 میلی ثانیه + یک میلی ثانیه - 1 دقیقه + یک دقیقه - 1 ثانیه + یک ثانیه - الان + الآن {0} هفته - 1 هفته + یک هفته {0} روز بعد @@ -211,7 +211,7 @@ {0} سال بعد - الان + الآن فردا From 598ba9efa540c4831a9543d8ddc2fdb87fd7afce Mon Sep 17 00:00:00 2001 From: Borzoo Date: Thu, 3 Apr 2014 15:46:27 +0430 Subject: [PATCH 4/7] Removed redundant space --- src/Humanizer.Tests/NumberToWordsTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Humanizer.Tests/NumberToWordsTests.cs b/src/Humanizer.Tests/NumberToWordsTests.cs index 16a3d98a8..ea9468499 100644 --- a/src/Humanizer.Tests/NumberToWordsTests.cs +++ b/src/Humanizer.Tests/NumberToWordsTests.cs @@ -37,6 +37,5 @@ public void ToWords(int number, string expected) { Assert.Equal(expected, number.ToWords()); } - } } From 89ed90f98363418907f5a3d972f191d1cd8ab552 Mon Sep 17 00:00:00 2001 From: brz Date: Thu, 3 Apr 2014 17:51:29 +0430 Subject: [PATCH 5/7] Added Farsi support to ToQuantityExtensions --- src/Humanizer.Tests/Humanizer.Tests.csproj | 1 + .../Localisation/fa/ToQuantityTests.cs | 48 +++++++++++++++++++ src/Humanizer/Humanizer.csproj | 3 ++ .../Quantifier/DefaultQuantifier.cs | 30 ++++++++++++ .../Quantifier/FarsiQuantifier.cs | 23 +++++++++ .../Quantifier/QuantifierFactory.cs | 34 +++++++++++++ .../Localisation/ResourceKeys.DateHumanize.cs | 6 ++- src/Humanizer/ToQuantityExtensions.cs | 17 ++----- 8 files changed, 148 insertions(+), 14 deletions(-) create mode 100644 src/Humanizer.Tests/Localisation/fa/ToQuantityTests.cs create mode 100644 src/Humanizer/Localisation/Quantifier/DefaultQuantifier.cs create mode 100644 src/Humanizer/Localisation/Quantifier/FarsiQuantifier.cs create mode 100644 src/Humanizer/Localisation/Quantifier/QuantifierFactory.cs diff --git a/src/Humanizer.Tests/Humanizer.Tests.csproj b/src/Humanizer.Tests/Humanizer.Tests.csproj index 240ae5aeb..a70958f62 100644 --- a/src/Humanizer.Tests/Humanizer.Tests.csproj +++ b/src/Humanizer.Tests/Humanizer.Tests.csproj @@ -86,6 +86,7 @@ + diff --git a/src/Humanizer.Tests/Localisation/fa/ToQuantityTests.cs b/src/Humanizer.Tests/Localisation/fa/ToQuantityTests.cs new file mode 100644 index 000000000..91c72bce8 --- /dev/null +++ b/src/Humanizer.Tests/Localisation/fa/ToQuantityTests.cs @@ -0,0 +1,48 @@ +using Xunit; +using Xunit.Extensions; + +namespace Humanizer.Tests.Localisation.fa +{ + public class ToQuantityTests : AmbientCulture + { + 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)); + } + } +} diff --git a/src/Humanizer/Humanizer.csproj b/src/Humanizer/Humanizer.csproj index 9c53de885..89dfc5354 100644 --- a/src/Humanizer/Humanizer.csproj +++ b/src/Humanizer/Humanizer.csproj @@ -75,6 +75,9 @@ + + + diff --git a/src/Humanizer/Localisation/Quantifier/DefaultQuantifier.cs b/src/Humanizer/Localisation/Quantifier/DefaultQuantifier.cs new file mode 100644 index 000000000..a3a3cd3b4 --- /dev/null +++ b/src/Humanizer/Localisation/Quantifier/DefaultQuantifier.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Humanizer.Localisation.Quantifier +{ + internal class DefaultQuantifier + { + 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); + } + } +} diff --git a/src/Humanizer/Localisation/Quantifier/FarsiQuantifier.cs b/src/Humanizer/Localisation/Quantifier/FarsiQuantifier.cs new file mode 100644 index 000000000..9d3b6e6b5 --- /dev/null +++ b/src/Humanizer/Localisation/Quantifier/FarsiQuantifier.cs @@ -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); + } + } +} diff --git a/src/Humanizer/Localisation/Quantifier/QuantifierFactory.cs b/src/Humanizer/Localisation/Quantifier/QuantifierFactory.cs new file mode 100644 index 000000000..f9c0f7bb7 --- /dev/null +++ b/src/Humanizer/Localisation/Quantifier/QuantifierFactory.cs @@ -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 DefaultQuantifier GetQuantifier(CultureInfo culture) + { + return GetQuantifier(culture.TwoLetterISOLanguageName); + } + + internal static DefaultQuantifier GetQuantifier() + { + return GetQuantifier(Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName); + } + + private static DefaultQuantifier GetQuantifier(string twoLetterISOLanguageName) + { + switch (twoLetterISOLanguageName) + { + case "fa": + return new FarsiQuantifier(); + default: + return new DefaultQuantifier(); + } + } + + } +} diff --git a/src/Humanizer/Localisation/ResourceKeys.DateHumanize.cs b/src/Humanizer/Localisation/ResourceKeys.DateHumanize.cs index 63f53699c..03347ab18 100644 --- a/src/Humanizer/Localisation/ResourceKeys.DateHumanize.cs +++ b/src/Humanizer/Localisation/ResourceKeys.DateHumanize.cs @@ -1,4 +1,6 @@ -namespace Humanizer.Localisation +using Humanizer.Localisation.Quantifier; +using System.Globalization; +namespace Humanizer.Localisation { public partial class ResourceKeys { @@ -34,7 +36,7 @@ public static string GetResourceKey(TimeUnit timeUnit, TimeUnitTense timeUnitTen var singularity = count == 1 ? Single : Multiple; var tense = timeUnitTense == TimeUnitTense.Future ? FromNow : Ago; - var unit = timeUnit.ToString().ToQuantity(count, ShowQuantityAs.None); + var unit = QuantifierFactory.GetQuantifier(CultureInfo.InvariantCulture).ToQuantity(timeUnit.ToString(), count, ShowQuantityAs.None); return DateTimeFormat.FormatWith(singularity, unit, tense); } } diff --git a/src/Humanizer/ToQuantityExtensions.cs b/src/Humanizer/ToQuantityExtensions.cs index 02ea1b252..501df1e24 100644 --- a/src/Humanizer/ToQuantityExtensions.cs +++ b/src/Humanizer/ToQuantityExtensions.cs @@ -1,4 +1,7 @@ -namespace Humanizer +using Humanizer.Localisation.Quantifier; +using System.Globalization; +using System.Threading; +namespace Humanizer { public enum ShowQuantityAs { @@ -25,17 +28,7 @@ public static class ToQuantityExtensions /// public static string ToQuantity(this string input, int quantity, ShowQuantityAs showQuantityAs = ShowQuantityAs.Numeric) { - var transformedInput = quantity == 1 - ? input.Singularize(Plurality.CouldBeEither) - : input.Pluralize(Plurality.CouldBeEither); - - 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); + return QuantifierFactory.GetQuantifier().ToQuantity(input, quantity, showQuantityAs); } } } From 2f715963b4421051d369728bbf97c236104d0d34 Mon Sep 17 00:00:00 2001 From: brz Date: Thu, 3 Apr 2014 18:18:29 +0430 Subject: [PATCH 6/7] Added Quantifier to Configurator --- src/Humanizer/Configuration/Configurator.cs | 9 +++++++++ src/Humanizer/Humanizer.csproj | 1 + .../Localisation/Quantifier/DefaultQuantifier.cs | 2 +- src/Humanizer/Localisation/Quantifier/IQuantifier.cs | 12 ++++++++++++ .../Localisation/Quantifier/QuantifierFactory.cs | 6 +++--- src/Humanizer/ToQuantityExtensions.cs | 5 +++-- 6 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 src/Humanizer/Localisation/Quantifier/IQuantifier.cs diff --git a/src/Humanizer/Configuration/Configurator.cs b/src/Humanizer/Configuration/Configurator.cs index 463f8e889..c0d9494e9 100644 --- a/src/Humanizer/Configuration/Configurator.cs +++ b/src/Humanizer/Configuration/Configurator.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Globalization; using Humanizer.Localisation; +using Humanizer.Localisation.Quantifier; namespace Humanizer.Configuration { @@ -33,5 +34,13 @@ public static IFormatter Formatter return new DefaultFormatter(); } } + + internal static IQuantifier Quantifier + { + get + { + return QuantifierFactory.GetQuantifier(); + } + } } } diff --git a/src/Humanizer/Humanizer.csproj b/src/Humanizer/Humanizer.csproj index 89dfc5354..ea0330dc8 100644 --- a/src/Humanizer/Humanizer.csproj +++ b/src/Humanizer/Humanizer.csproj @@ -77,6 +77,7 @@ + diff --git a/src/Humanizer/Localisation/Quantifier/DefaultQuantifier.cs b/src/Humanizer/Localisation/Quantifier/DefaultQuantifier.cs index a3a3cd3b4..e5b482818 100644 --- a/src/Humanizer/Localisation/Quantifier/DefaultQuantifier.cs +++ b/src/Humanizer/Localisation/Quantifier/DefaultQuantifier.cs @@ -5,7 +5,7 @@ namespace Humanizer.Localisation.Quantifier { - internal class DefaultQuantifier + internal class DefaultQuantifier : IQuantifier { public string ToQuantity(string input, int quantity, ShowQuantityAs showQuantityAs) { diff --git a/src/Humanizer/Localisation/Quantifier/IQuantifier.cs b/src/Humanizer/Localisation/Quantifier/IQuantifier.cs new file mode 100644 index 000000000..d3aba6479 --- /dev/null +++ b/src/Humanizer/Localisation/Quantifier/IQuantifier.cs @@ -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); + } +} diff --git a/src/Humanizer/Localisation/Quantifier/QuantifierFactory.cs b/src/Humanizer/Localisation/Quantifier/QuantifierFactory.cs index f9c0f7bb7..0eca7cf47 100644 --- a/src/Humanizer/Localisation/Quantifier/QuantifierFactory.cs +++ b/src/Humanizer/Localisation/Quantifier/QuantifierFactory.cs @@ -9,17 +9,17 @@ namespace Humanizer.Localisation.Quantifier { internal class QuantifierFactory { - internal static DefaultQuantifier GetQuantifier(CultureInfo culture) + internal static IQuantifier GetQuantifier(CultureInfo culture) { return GetQuantifier(culture.TwoLetterISOLanguageName); } - internal static DefaultQuantifier GetQuantifier() + internal static IQuantifier GetQuantifier() { return GetQuantifier(Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName); } - private static DefaultQuantifier GetQuantifier(string twoLetterISOLanguageName) + private static IQuantifier GetQuantifier(string twoLetterISOLanguageName) { switch (twoLetterISOLanguageName) { diff --git a/src/Humanizer/ToQuantityExtensions.cs b/src/Humanizer/ToQuantityExtensions.cs index 501df1e24..5b8d4792a 100644 --- a/src/Humanizer/ToQuantityExtensions.cs +++ b/src/Humanizer/ToQuantityExtensions.cs @@ -1,4 +1,5 @@ -using Humanizer.Localisation.Quantifier; +using Humanizer.Configuration; +using Humanizer.Localisation.Quantifier; using System.Globalization; using System.Threading; namespace Humanizer @@ -28,7 +29,7 @@ public static class ToQuantityExtensions /// public static string ToQuantity(this string input, int quantity, ShowQuantityAs showQuantityAs = ShowQuantityAs.Numeric) { - return QuantifierFactory.GetQuantifier().ToQuantity(input, quantity, showQuantityAs); + return Configurator.Quantifier.ToQuantity(input, quantity, showQuantityAs); } } } From 52aa3f405497760be74aa001e0d873f1b128d69d Mon Sep 17 00:00:00 2001 From: brz Date: Fri, 4 Apr 2014 00:08:17 +0430 Subject: [PATCH 7/7] Updated release_notes --- release_notes.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/release_notes.md b/release_notes.md index 86150d068..e449a66f8 100644 --- a/release_notes.md +++ b/release_notes.md @@ -1,7 +1,8 @@ ###v1.16.1 - 2014-04-03 - [#121] (https://github.com/MehdiK/Humanizer/pull/121) : Added Farsi support to DateTime and NumberToWords + - Added Farsi support to ToQuantityExtensions -[Commits](https://github.com/MehdiK/Humanizer/compare/v1.15.1...master) +[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'