diff --git a/.gitignore b/.gitignore index f58dc1baa..4212daa65 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,6 @@ PackageBuild/* Build/* src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.received.txt *.tss -src/TestResults/* \ No newline at end of file +src/TestResults/* +# Roslyn's metadata directory +*.sln.ide/ \ No newline at end of file diff --git a/release_notes.md b/release_notes.md index 3ce0524ef..28a1811e2 100644 --- a/release_notes.md +++ b/release_notes.md @@ -4,6 +4,7 @@ - [#190](https://github.com/MehdiK/Humanizer/pull/190): Added French translation for ToWords and ToOrdinalWords - [#179](https://github.com/MehdiK/Humanizer/pull/179): Adding Hungarian localisation - [#181](https://github.com/Mehdik/Humanizer/pull/181): Added Bulgarian localization, date and timespan tests + - [#148](https://github.com/Mehdik/Humanizer/pull/148): Adding Hebrew localization for date and timespan [Commits](https://github.com/MehdiK/Humanizer/compare/v1.20.15...master) diff --git a/src/Humanizer.Tests/Humanizer.Tests.csproj b/src/Humanizer.Tests/Humanizer.Tests.csproj index d35f84148..3f8f50539 100644 --- a/src/Humanizer.Tests/Humanizer.Tests.csproj +++ b/src/Humanizer.Tests/Humanizer.Tests.csproj @@ -92,6 +92,8 @@ + + @@ -102,7 +104,7 @@ - + diff --git a/src/Humanizer.Tests/Localisation/he/DateHumanizeTests.cs b/src/Humanizer.Tests/Localisation/he/DateHumanizeTests.cs new file mode 100644 index 000000000..f44f1c73f --- /dev/null +++ b/src/Humanizer.Tests/Localisation/he/DateHumanizeTests.cs @@ -0,0 +1,72 @@ +using System; +using Humanizer.Localisation; +using Xunit; +using Xunit.Extensions; + +namespace Humanizer.Tests.Localisation.he +{ + public class DateHumanizeTests : AmbientCulture + { + public DateHumanizeTests() : base("he") { } + + [Theory] + [InlineData(-1, "אתמול")] + [InlineData(-2, "לפני יומיים")] + [InlineData(-3, "לפני 3 ימים")] + [InlineData(-11, "לפני 11 יום")] + public void DaysAgo(int days, string expected) + { + DateHumanize.Verify(expected, days, TimeUnit.Day, Tense.Past); + } + + [Theory] + [InlineData(-2, "לפני שעתיים")] + [InlineData(-1, "לפני שעה")] + [InlineData(-3, "לפני 3 שעות")] + [InlineData(-11, "לפני 11 שעות")] + public void HoursAgo(int hours, string expected) + { + DateHumanize.Verify(expected, hours, TimeUnit.Hour, Tense.Past); + } + + [Theory] + [InlineData(-2, "לפני 2 דקות")] + [InlineData(-1, "לפני דקה")] + [InlineData(-3, "לפני 3 דקות")] + [InlineData(-11, "לפני 11 דקות")] + public void MinutesAgo(int minutes, string expected) + { + DateHumanize.Verify(expected, minutes, TimeUnit.Minute, Tense.Past); + } + + [Theory] + [InlineData(-2, "לפני חודשיים")] + [InlineData(-1, "לפני חודש")] + [InlineData(-3, "לפני 3 חודשים")] + [InlineData(-11, "לפני 11 חודשים")] + public void MonthsAgo(int months, string expected) + { + DateHumanize.Verify(expected, months, TimeUnit.Month, Tense.Past); + } + + [Theory] + [InlineData(-2, "לפני 2 שניות")] + [InlineData(-1, "לפני שנייה")] + [InlineData(-3, "לפני 3 שניות")] + [InlineData(-11, "לפני 11 שניות")] + public void SecondsAgo(int seconds, string expected) + { + DateHumanize.Verify(expected, seconds, TimeUnit.Second, Tense.Past); + } + + [Theory] + [InlineData(-2, "לפני שנתיים")] + [InlineData(-1, "לפני שנה")] + [InlineData(-3, "לפני 3 שנים")] + [InlineData(-11, "לפני 11 שנה")] + public void YearsAgo(int years, string expected) + { + DateHumanize.Verify(expected, years, TimeUnit.Year, Tense.Past); + } + } +} diff --git a/src/Humanizer.Tests/Localisation/he/TimeSpanHumanizeTests.cs b/src/Humanizer.Tests/Localisation/he/TimeSpanHumanizeTests.cs new file mode 100644 index 000000000..03ca8097d --- /dev/null +++ b/src/Humanizer.Tests/Localisation/he/TimeSpanHumanizeTests.cs @@ -0,0 +1,78 @@ +using System; +using Xunit; +using Xunit.Extensions; + +namespace Humanizer.Tests.Localisation.he +{ + public class TimeSpanHumanizeTests : AmbientCulture + { + public TimeSpanHumanizeTests() : base("he") { } + + [Theory] + [InlineData(7, "שבוע")] + [InlineData(14, "שבועיים")] + [InlineData(21, "3 שבועות")] + [InlineData(77, "11 שבועות")] + public void Weeks(int days, string expected) + { + Assert.Equal(expected, TimeSpan.FromDays(days).Humanize()); + } + + + [Theory] + [InlineData(1, "יום")] + [InlineData(2, "יומיים")] + [InlineData(3, "3 ימים")] + public void Days(int days, string expected) + { + Assert.Equal(expected, TimeSpan.FromDays(days).Humanize()); + } + + [Theory] + [InlineData(1, "שעה")] + [InlineData(2, "שעתיים")] + [InlineData(3, "3 שעות")] + [InlineData(11, "11 שעות")] + public void Hours(int hours, string expected) + { + Assert.Equal(expected, TimeSpan.FromHours(hours).Humanize()); + } + + [Theory] + [InlineData(1, "דקה")] + [InlineData(2, "שתי דקות")] + [InlineData(3, "3 דקות")] + [InlineData(11, "11 דקות")] + public void Minutes(int minutes, string expected) + { + Assert.Equal(expected, TimeSpan.FromMinutes(minutes).Humanize()); + } + + + [Theory] + [InlineData(1, "שנייה")] + [InlineData(2, "שתי שניות")] + [InlineData(3, "3 שניות")] + [InlineData(11, "11 שניות")] + public void Seconds(int seconds, string expected) + { + Assert.Equal(expected, TimeSpan.FromSeconds(seconds).Humanize()); + } + + [Theory] + [InlineData(1, "אלפית שנייה")] + [InlineData(2, "שתי אלפיות שנייה")] + [InlineData(3, "3 אלפיות שנייה")] + [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/Configuration/Configurator.cs b/src/Humanizer/Configuration/Configurator.cs index fbf52af16..4d7bfc00e 100644 --- a/src/Humanizer/Configuration/Configurator.cs +++ b/src/Humanizer/Configuration/Configurator.cs @@ -17,6 +17,7 @@ public static class Configurator { "ro", () => new RomanianFormatter() }, { "ru", () => new RussianFormatter() }, { "ar", () => new ArabicFormatter() }, + { "he", () => new HebrewFormatter() }, { "sk", () => new CzechSlovakPolishFormatter() }, { "cs", () => new CzechSlovakPolishFormatter() }, { "pl", () => new CzechSlovakPolishFormatter() } diff --git a/src/Humanizer/Humanizer.csproj b/src/Humanizer/Humanizer.csproj index 22e30a94d..9a2639b9c 100644 --- a/src/Humanizer/Humanizer.csproj +++ b/src/Humanizer/Humanizer.csproj @@ -87,6 +87,7 @@ + @@ -162,6 +163,7 @@ + diff --git a/src/Humanizer/Localisation/Formatters/HebrewFormatter.cs b/src/Humanizer/Localisation/Formatters/HebrewFormatter.cs new file mode 100644 index 000000000..23542079f --- /dev/null +++ b/src/Humanizer/Localisation/Formatters/HebrewFormatter.cs @@ -0,0 +1,22 @@ +namespace Humanizer.Localisation.Formatters +{ + internal class HebrewFormatter : DefaultFormatter + { + private const string DualPostfix = "_Dual"; + private const string PluralPostfix = "_Plural"; + + protected override string GetResourceKey(string resourceKey, int number) + { + //In Hebrew pluralization 2 entities gets a different word. + if (number == 2) + return resourceKey + DualPostfix; + + //In Hebrew pluralization entities where the count is between 3 and 10 gets a different word. + //See http://lib.cet.ac.il/pages/item.asp?item=21585 for explanation + if (number >= 3 && number <= 10) + return resourceKey + PluralPostfix; + + return resourceKey; + } + } +} \ No newline at end of file diff --git a/src/Humanizer/Properties/Resources.he.resx b/src/Humanizer/Properties/Resources.he.resx new file mode 100644 index 000000000..d446da912 --- /dev/null +++ b/src/Humanizer/Properties/Resources.he.resx @@ -0,0 +1,316 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + לפני שנייה + one second ago + + + לפני {0} שניות + {0} seconds ago + + + לפני דקה + a minute ago + + + לפני {0} דקות + {0} minutes ago + + + לפני שעה + an hour ago + + + לפני {0} שעות + {0} hours ago + + + אתמול + yesterday + + + לפני {0} יום + {0} days ago + + + לפני חודש + one month ago + + + לפני {0} חודשים + {0} months ago + + + לפני שנה + one year ago + + + לפני {0} שנה + {0} years ago + + + יום + single day + + + שעה + single hour + + + אלפית שנייה + single millisecond + + + דקה + single minute + + + שנייה + single second + + + שבוע + single week + + + אין זמן + no time + + + לפני יומיים + two days ago + + + לפני שעתיים + two hours ago + + + לפני {0} דקות + two minutes ago + + + לפני חודשיים + two months ago + + + לפני {0} שניות + 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