From 151a0d8ab85911acc3c040fecc09ff3644b60792 Mon Sep 17 00:00:00 2001 From: Spoc Web <10584012+SpocWeb@users.noreply.github.com> Date: Tue, 27 Dec 2022 12:43:57 +0100 Subject: [PATCH 1/6] added German TimeOnlyToClockNotation --- .../Humanizer.Tests.Shared.projitems | 1 + .../de/TimeToClockNotationTests.cs | 88 +++++++++++++++++ .../NumberToWordsTests.cs | 2 +- ...meOnlyToClockNotationConvertersRegistry.cs | 1 + .../Ordinalizers/EnglishOrdinalizer.cs | 23 ++--- .../DeTimeOnlyToClockNotationConverter.cs | 94 +++++++++++++++++++ 6 files changed, 193 insertions(+), 16 deletions(-) create mode 100644 src/Humanizer.Tests.Shared/Localisation/de/TimeToClockNotationTests.cs create mode 100644 src/Humanizer/Localisation/TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs diff --git a/src/Humanizer.Tests.Shared/Humanizer.Tests.Shared.projitems b/src/Humanizer.Tests.Shared/Humanizer.Tests.Shared.projitems index 51bc3c02b..e13e66230 100644 --- a/src/Humanizer.Tests.Shared/Humanizer.Tests.Shared.projitems +++ b/src/Humanizer.Tests.Shared/Humanizer.Tests.Shared.projitems @@ -25,6 +25,7 @@ + diff --git a/src/Humanizer.Tests.Shared/Localisation/de/TimeToClockNotationTests.cs b/src/Humanizer.Tests.Shared/Localisation/de/TimeToClockNotationTests.cs new file mode 100644 index 000000000..89d8e1f08 --- /dev/null +++ b/src/Humanizer.Tests.Shared/Localisation/de/TimeToClockNotationTests.cs @@ -0,0 +1,88 @@ +#if NET6_0_OR_GREATER + +using System; +using System.Diagnostics.CodeAnalysis; + +using Humanizer; +using Humanizer.Tests; + +using Xunit; + +namespace org.SpocWeb.root.NaturalLang.Tests.de; + +[UseCulture("de-DE")] +[SuppressMessage("ReSharper", "StringLiteralTypo")] +public static class TimeToClockNotationTests +{ + #region [InlineData(0, 0, "")] + + [Theory] + [InlineData(0, 0, "Mitternacht")] + [InlineData(0, 7, "12 Uhr 7 nachts")] + [InlineData(1, 11, "1 Uhr 11 nachts")] + [InlineData(4, 0, "4 Uhr nachts")] + [InlineData(5, 1, "5 Uhr 1 nachts")] + [InlineData(6, 0, "6 Uhr morgens")] + [InlineData(6, 5, "fünf nach 6 morgens")] + [InlineData(7, 10, "zehn nach 7 morgens")] + [InlineData(8, 15, "Viertel nach 8 morgens")] + [InlineData(9, 20, "zwanzig nach 9 morgens")] + [InlineData(10, 25, "fünf vor halb 11 morgens")] + [InlineData(11, 30, "halb 12 morgens")] + [InlineData(12, 00, "Mittag")] + [InlineData(12, 38, "12 Uhr 38 nachmittags")] + [InlineData(12, 35, "fünf nach halb 1 nachmittags")] + [InlineData(15, 40, "zwanzig vor 4 nachmittags")] + [InlineData(17, 45, "Viertel vor 6 nachmittags")] + [InlineData(19, 50, "zehn vor 8 abends")] + [InlineData(21, 0, "9 Uhr abends")] + [InlineData(21, 55, "fünf vor 10 abends")] + [InlineData(22, 59, "10 Uhr 59 abends")] + [InlineData(23, 43, "11 Uhr 43 abends")] + + #endregion [InlineData(0, 0, "")] + + public static void ConvertToClockNotationTimeOnlyStringDe(int hours, int minutes, string expectedResult) + { + var actualResult = new TimeOnly(hours, minutes).ToClockNotation(); + Assert.Equal(expectedResult, actualResult); + } + + + #region [InlineData(0, 0, "")] + + [Theory] + [InlineData(0, 0, "Mitternacht")] + [InlineData(0, 7, "fünf nach 12 nachts")] + [InlineData(1, 11, "zehn nach 1 nachts")] + [InlineData(4, 0, "4 Uhr nachts")] + [InlineData(5, 1, "5 Uhr nachts")] + [InlineData(6, 0, "6 Uhr morgens")] + [InlineData(6, 5, "fünf nach 6 morgens")] + [InlineData(7, 10, "zehn nach 7 morgens")] + [InlineData(8, 15, "Viertel nach 8 morgens")] + [InlineData(9, 20, "zwanzig nach 9 morgens")] + [InlineData(10, 25, "fünf vor halb 11 morgens")] + [InlineData(11, 30, "halb 12 morgens")] + [InlineData(12, 00, "Mittag")] + [InlineData(12, 38, "zwanzig vor 1 nachmittags")] + [InlineData(12, 35, "fünf nach halb 1 nachmittags")] + [InlineData(15, 40, "zwanzig vor 4 nachmittags")] + [InlineData(17, 45, "Viertel vor 6 nachmittags")] + [InlineData(19, 50, "zehn vor 8 abends")] + [InlineData(21, 0, "9 Uhr abends")] + [InlineData(21, 55, "fünf vor 10 abends")] + [InlineData(22, 59, "11 Uhr abends")] + [InlineData(23, 43, "Viertel vor 12 abends")] + [InlineData(23, 58, "Mitternacht")] + + #endregion [InlineData(0, 0, "")] + + public static void ConvertToRoundedClockNotationTimeOnlyStringPtBr(int hours, int minutes, string expectedResult) + { + var actualResult = new TimeOnly(hours, minutes).ToClockNotation(ClockNotationRounding.NearestFiveMinutes); + Assert.Equal(expectedResult, actualResult); + } +} + +#endif diff --git a/src/Humanizer.Tests.Shared/NumberToWordsTests.cs b/src/Humanizer.Tests.Shared/NumberToWordsTests.cs index 4346b215e..2b6d3fe37 100644 --- a/src/Humanizer.Tests.Shared/NumberToWordsTests.cs +++ b/src/Humanizer.Tests.Shared/NumberToWordsTests.cs @@ -130,7 +130,7 @@ public void ToTuple(int number, string expected) [InlineData(11, "ta", "பதினொன்று")] [InlineData(12, "ta", "பனிரெண்டு")] [InlineData(555, "ta", "ஐந்நூற்று ஐம்பத்து ஐந்து")] - public void ToWords_CanSpecifyCultureExplicitly(int number, string culture, string expected) + public void b(int number, string culture, string expected) { Assert.Equal(expected, number.ToWords(new CultureInfo(culture))); } diff --git a/src/Humanizer/Configuration/TimeOnlyToClockNotationConvertersRegistry.cs b/src/Humanizer/Configuration/TimeOnlyToClockNotationConvertersRegistry.cs index 91fb9ff2e..d7d00643c 100644 --- a/src/Humanizer/Configuration/TimeOnlyToClockNotationConvertersRegistry.cs +++ b/src/Humanizer/Configuration/TimeOnlyToClockNotationConvertersRegistry.cs @@ -11,6 +11,7 @@ public TimeOnlyToClockNotationConvertersRegistry() : base(new DefaultTimeOnlyToC Register("pt-BR", new BrazilianPortugueseTimeOnlyToClockNotationConverter()); Register("fr", new FrTimeOnlyToClockNotationConverter()); Register("es", new EsTimeOnlyToClockNotationConverter()); + Register("de", new DeTimeOnlyToClockNotationConverter()); } } } diff --git a/src/Humanizer/Localisation/Ordinalizers/EnglishOrdinalizer.cs b/src/Humanizer/Localisation/Ordinalizers/EnglishOrdinalizer.cs index efe30247d..9ff364922 100644 --- a/src/Humanizer/Localisation/Ordinalizers/EnglishOrdinalizer.cs +++ b/src/Humanizer/Localisation/Ordinalizers/EnglishOrdinalizer.cs @@ -6,25 +6,18 @@ public override string Convert(int number, string numberString) { var nMod100 = number % 100; - if (nMod100 >= 11 && nMod100 <= 13) + if (nMod100 is >= 11 and <= 13) { return numberString + "th"; } - switch (number % 10) + return (number % 10) switch { - case 1: - return numberString + "st"; - - case 2: - return numberString + "nd"; - - case 3: - return numberString + "rd"; - - default: - return numberString + "th"; - } + 1 => numberString + "st", + 2 => numberString + "nd", + 3 => numberString + "rd", + _ => numberString + "th" + }; } } -} \ No newline at end of file +} diff --git a/src/Humanizer/Localisation/TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs b/src/Humanizer/Localisation/TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs new file mode 100644 index 000000000..6975c0bf0 --- /dev/null +++ b/src/Humanizer/Localisation/TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs @@ -0,0 +1,94 @@ +#if NET6_0_OR_GREATER + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace Humanizer.Localisation.TimeToClockNotation; + +public class DeTimeOnlyToClockNotationConverter : ITimeOnlyToClockNotationConverter +{ + /// Switch to output Digits as Words + public bool AsWords; + + /// Used to pre-pend, append or omit the Quarter of the Day + public bool? PrePendQuarter = false; + + public string Convert(TimeOnly time, ClockNotationRounding roundToNearestFive) + { + var ret = time.AsClockDe(roundToNearestFive, AsWords); + if (!PrePendQuarter.HasValue + || ret == German.MidNight + || ret == German.MidDay) + { + return ret; + } + return PrePendQuarter switch + { + false => ret + ' ' + time.GetDayQuarterGermanGenitive(), + true => time.GetDayQuarterGermanGenitive() + ' ' + ret, _ => ret + }; + } +} + +public static class German +{ + public const string MidNight = "Mitternacht"; + public const string MidDay = "Mittag"; + + public static readonly IReadOnlyList QuarterDay = new[] {"Nacht", "Morgen", "Nachmittag", "Abend"}; + + public static string GetDayQuarterGerman(this TimeOnly time) => QuarterDay[time.Hour / 6]; + public static string GetDayQuarterGermanGenitive(this TimeOnly time) => GetDayQuarterGerman(time).ToLower() + "s"; + + /// Use 12 Hours but avoid 0 + private static int NormalizeHour(TimeOnly time) => time.Hour % 12 != 0 ? (time.Hour % 12) : 12; + + [SuppressMessage("ReSharper", "StringLiteralTypo")] + public static string AsClockDe(this TimeOnly time, ClockNotationRounding round, bool asWords = false) + { + if (round == ClockNotationRounding.NearestFiveMinutes) + { + var ticks = 5 * TimeSpan.TicksPerMinute; + var quotient = (time.Ticks + ticks / 2) / ticks; + var total = quotient * ticks; + if (total >= TimeSpan.TicksPerDay) + { + total -= TimeSpan.TicksPerDay; + } + time = new TimeOnly(total); + } + switch (time) + { + case { Hour: 0, Minute: 0 }: return MidNight; + case { Hour: 12, Minute: 0 }: return MidDay; + } + + var addHour = time.AddHours(1); + var hours = NormalizeHour(time); + var hour = asWords ? hours.ToWords() : hours.ToString(); + var nextHours = NormalizeHour(addHour); + var nextHour = asWords ? nextHours.ToWords() : nextHours.ToString(); + + return time.Minute switch + { + 00 => $"{hour} Uhr", + 05 => $"fünf nach {hour}", + 10 => $"zehn nach {hour}", + 15 => $"Viertel nach {hour}", + 20 => $"zwanzig nach {hour}", + 25 => $"fünf vor halb {nextHour}", + 30 => $"halb {nextHour}", + 35 => $"fünf nach halb {nextHour}", + 40 => $"zwanzig vor {nextHour}", + 45 => $"Viertel vor {nextHour}", + 50 => $"zehn vor {nextHour}", + 55 => $"fünf vor {nextHour}", + 60 => $"{nextHour} Uhr", + _ => $"{hour} Uhr {time.Minute}" //.AsWords() + }; + } + +} + +#endif From 7b6f44b6ba0c2f5db10398492392faadf3aa8426 Mon Sep 17 00:00:00 2001 From: Spoc Web <10584012+SpocWeb@users.noreply.github.com> Date: Tue, 27 Dec 2022 12:51:03 +0100 Subject: [PATCH 2/6] removed Curlies around single-Line --- .../DeTimeOnlyToClockNotationConverter.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Humanizer/Localisation/TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs b/src/Humanizer/Localisation/TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs index 6975c0bf0..4b435960c 100644 --- a/src/Humanizer/Localisation/TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs +++ b/src/Humanizer/Localisation/TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs @@ -20,13 +20,12 @@ public string Convert(TimeOnly time, ClockNotationRounding roundToNearestFive) if (!PrePendQuarter.HasValue || ret == German.MidNight || ret == German.MidDay) - { return ret; - } - return PrePendQuarter switch + + return PrePendQuarter.Value switch { false => ret + ' ' + time.GetDayQuarterGermanGenitive(), - true => time.GetDayQuarterGermanGenitive() + ' ' + ret, _ => ret + true => time.GetDayQuarterGermanGenitive() + ' ' + ret }; } } From 8b16f946046c9260eb140ea7d5f548ce911f09ba Mon Sep 17 00:00:00 2001 From: Spoc Web <10584012+SpocWeb@users.noreply.github.com> Date: Tue, 27 Dec 2022 16:12:59 +0100 Subject: [PATCH 3/6] adjusted public API, which is udeful on its own. --- ...pprovalTest.approve_public_api.approved.txt | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt index 746484da8..205e7682e 100644 --- a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt +++ b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt @@ -1,5 +1,5 @@ [assembly: System.Resources.NeutralResourcesLanguageAttribute("en")] -[assembly: System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName="")] +[assembly: System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName=".NET 6.0")] namespace Humanizer { public class static ByteSizeExtensions @@ -1985,6 +1985,22 @@ namespace Humanizer.Localisation.Ordinalizers } namespace Humanizer.Localisation.TimeToClockNotation { + public class DeTimeOnlyToClockNotationConverter : Humanizer.Localisation.TimeToClockNotation.ITimeOnlyToClockNotationConverter + { + public bool AsWords; + public System.Nullable PrePendQuarter; + public DeTimeOnlyToClockNotationConverter() { } + public string Convert(System.TimeOnly time, Humanizer.ClockNotationRounding roundToNearestFive) { } + } + public class static German + { + public const string MidDay = "Mittag"; + public const string MidNight = "Mitternacht"; + public static readonly System.Collections.Generic.IReadOnlyList QuarterDay; + public static string AsClockDe(this System.TimeOnly time, Humanizer.ClockNotationRounding round, bool asWords = False) { } + public static string GetDayQuarterGerman(this System.TimeOnly time) { } + public static string GetDayQuarterGermanGenitive(this System.TimeOnly time) { } + } public interface ITimeOnlyToClockNotationConverter { string Convert(System.TimeOnly time, Humanizer.ClockNotationRounding roundToNearestFive); From d41f0bf96c12eedf5903d8564417a51556a86910 Mon Sep 17 00:00:00 2001 From: Spoc Web <10584012+SpocWeb@users.noreply.github.com> Date: Tue, 27 Dec 2022 16:28:05 +0100 Subject: [PATCH 4/6] fixed FW in ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt --- .../PublicApiApprovalTest.approve_public_api.approved.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt index 205e7682e..fd1612904 100644 --- a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt +++ b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt @@ -1,5 +1,5 @@ [assembly: System.Resources.NeutralResourcesLanguageAttribute("en")] -[assembly: System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName=".NET 6.0")] +[assembly: System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName="")] namespace Humanizer { public class static ByteSizeExtensions From 0df5da4dcd8165fce04b5f35b66975a5111146cc Mon Sep 17 00:00:00 2001 From: Spoc Web <10584012+SpocWeb@users.noreply.github.com> Date: Tue, 27 Dec 2022 20:27:25 +0100 Subject: [PATCH 5/6] fixed Comments on PR --- .../de/TimeToClockNotationTests.cs | 5 +- .../NumberToWordsTests.cs | 2 +- ...provalTest.approve_public_api.approved.txt | 7 -- .../DeTimeOnlyToClockNotationConverter.cs | 64 +----------------- .../TimeToClockNotation/German.cs | 67 +++++++++++++++++++ 5 files changed, 70 insertions(+), 75 deletions(-) create mode 100644 src/Humanizer/Localisation/TimeToClockNotation/German.cs diff --git a/src/Humanizer.Tests.Shared/Localisation/de/TimeToClockNotationTests.cs b/src/Humanizer.Tests.Shared/Localisation/de/TimeToClockNotationTests.cs index 89d8e1f08..9c2b5bc97 100644 --- a/src/Humanizer.Tests.Shared/Localisation/de/TimeToClockNotationTests.cs +++ b/src/Humanizer.Tests.Shared/Localisation/de/TimeToClockNotationTests.cs @@ -3,12 +3,9 @@ using System; using System.Diagnostics.CodeAnalysis; -using Humanizer; -using Humanizer.Tests; - using Xunit; -namespace org.SpocWeb.root.NaturalLang.Tests.de; +namespace Humanizer.Tests.Localisation.de; [UseCulture("de-DE")] [SuppressMessage("ReSharper", "StringLiteralTypo")] diff --git a/src/Humanizer.Tests.Shared/NumberToWordsTests.cs b/src/Humanizer.Tests.Shared/NumberToWordsTests.cs index 2b6d3fe37..4346b215e 100644 --- a/src/Humanizer.Tests.Shared/NumberToWordsTests.cs +++ b/src/Humanizer.Tests.Shared/NumberToWordsTests.cs @@ -130,7 +130,7 @@ public void ToTuple(int number, string expected) [InlineData(11, "ta", "பதினொன்று")] [InlineData(12, "ta", "பனிரெண்டு")] [InlineData(555, "ta", "ஐந்நூற்று ஐம்பத்து ஐந்து")] - public void b(int number, string culture, string expected) + public void ToWords_CanSpecifyCultureExplicitly(int number, string culture, string expected) { Assert.Equal(expected, number.ToWords(new CultureInfo(culture))); } diff --git a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt index fd1612904..e32d282e5 100644 --- a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt +++ b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt @@ -1985,13 +1985,6 @@ namespace Humanizer.Localisation.Ordinalizers } namespace Humanizer.Localisation.TimeToClockNotation { - public class DeTimeOnlyToClockNotationConverter : Humanizer.Localisation.TimeToClockNotation.ITimeOnlyToClockNotationConverter - { - public bool AsWords; - public System.Nullable PrePendQuarter; - public DeTimeOnlyToClockNotationConverter() { } - public string Convert(System.TimeOnly time, Humanizer.ClockNotationRounding roundToNearestFive) { } - } public class static German { public const string MidDay = "Mittag"; diff --git a/src/Humanizer/Localisation/TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs b/src/Humanizer/Localisation/TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs index 4b435960c..7ab581c0b 100644 --- a/src/Humanizer/Localisation/TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs +++ b/src/Humanizer/Localisation/TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs @@ -1,12 +1,10 @@ #if NET6_0_OR_GREATER using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace Humanizer.Localisation.TimeToClockNotation; -public class DeTimeOnlyToClockNotationConverter : ITimeOnlyToClockNotationConverter +internal class DeTimeOnlyToClockNotationConverter : ITimeOnlyToClockNotationConverter { /// Switch to output Digits as Words public bool AsWords; @@ -30,64 +28,4 @@ public string Convert(TimeOnly time, ClockNotationRounding roundToNearestFive) } } -public static class German -{ - public const string MidNight = "Mitternacht"; - public const string MidDay = "Mittag"; - - public static readonly IReadOnlyList QuarterDay = new[] {"Nacht", "Morgen", "Nachmittag", "Abend"}; - - public static string GetDayQuarterGerman(this TimeOnly time) => QuarterDay[time.Hour / 6]; - public static string GetDayQuarterGermanGenitive(this TimeOnly time) => GetDayQuarterGerman(time).ToLower() + "s"; - - /// Use 12 Hours but avoid 0 - private static int NormalizeHour(TimeOnly time) => time.Hour % 12 != 0 ? (time.Hour % 12) : 12; - - [SuppressMessage("ReSharper", "StringLiteralTypo")] - public static string AsClockDe(this TimeOnly time, ClockNotationRounding round, bool asWords = false) - { - if (round == ClockNotationRounding.NearestFiveMinutes) - { - var ticks = 5 * TimeSpan.TicksPerMinute; - var quotient = (time.Ticks + ticks / 2) / ticks; - var total = quotient * ticks; - if (total >= TimeSpan.TicksPerDay) - { - total -= TimeSpan.TicksPerDay; - } - time = new TimeOnly(total); - } - switch (time) - { - case { Hour: 0, Minute: 0 }: return MidNight; - case { Hour: 12, Minute: 0 }: return MidDay; - } - - var addHour = time.AddHours(1); - var hours = NormalizeHour(time); - var hour = asWords ? hours.ToWords() : hours.ToString(); - var nextHours = NormalizeHour(addHour); - var nextHour = asWords ? nextHours.ToWords() : nextHours.ToString(); - - return time.Minute switch - { - 00 => $"{hour} Uhr", - 05 => $"fünf nach {hour}", - 10 => $"zehn nach {hour}", - 15 => $"Viertel nach {hour}", - 20 => $"zwanzig nach {hour}", - 25 => $"fünf vor halb {nextHour}", - 30 => $"halb {nextHour}", - 35 => $"fünf nach halb {nextHour}", - 40 => $"zwanzig vor {nextHour}", - 45 => $"Viertel vor {nextHour}", - 50 => $"zehn vor {nextHour}", - 55 => $"fünf vor {nextHour}", - 60 => $"{nextHour} Uhr", - _ => $"{hour} Uhr {time.Minute}" //.AsWords() - }; - } - -} - #endif diff --git a/src/Humanizer/Localisation/TimeToClockNotation/German.cs b/src/Humanizer/Localisation/TimeToClockNotation/German.cs new file mode 100644 index 000000000..52c490e14 --- /dev/null +++ b/src/Humanizer/Localisation/TimeToClockNotation/German.cs @@ -0,0 +1,67 @@ +#if NET6_0_OR_GREATER +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace Humanizer.Localisation.TimeToClockNotation; + +public static class German +{ + public const string MidNight = "Mitternacht"; + public const string MidDay = "Mittag"; + + public static readonly IReadOnlyList QuarterDay = new[] {"Nacht", "Morgen", "Nachmittag", "Abend"}; + + public static string GetDayQuarterGerman(this TimeOnly time) => QuarterDay[time.Hour / 6]; + public static string GetDayQuarterGermanGenitive(this TimeOnly time) => GetDayQuarterGerman(time).ToLower() + "s"; + + /// Use 12 Hours but avoid 0 + private static int NormalizeHour(TimeOnly time) => time.Hour % 12 != 0 ? (time.Hour % 12) : 12; + + [SuppressMessage("ReSharper", "StringLiteralTypo")] + public static string AsClockDe(this TimeOnly time, ClockNotationRounding round, bool asWords = false) + { + if (round == ClockNotationRounding.NearestFiveMinutes) + { + var ticks = 5 * TimeSpan.TicksPerMinute; + var quotient = (time.Ticks + ticks / 2) / ticks; + var total = quotient * ticks; + if (total >= TimeSpan.TicksPerDay) + { + total -= TimeSpan.TicksPerDay; + } + time = new TimeOnly(total); + } + switch (time) + { + case { Hour: 0, Minute: 0 }: return MidNight; + case { Hour: 12, Minute: 0 }: return MidDay; + } + + var addHour = time.AddHours(1); + var hours = NormalizeHour(time); + var hour = asWords ? hours.ToWords() : hours.ToString(); + var nextHours = NormalizeHour(addHour); + var nextHour = asWords ? nextHours.ToWords() : nextHours.ToString(); + + return time.Minute switch + { + 00 => $"{hour} Uhr", + 05 => $"fünf nach {hour}", + 10 => $"zehn nach {hour}", + 15 => $"Viertel nach {hour}", + 20 => $"zwanzig nach {hour}", + 25 => $"fünf vor halb {nextHour}", + 30 => $"halb {nextHour}", + 35 => $"fünf nach halb {nextHour}", + 40 => $"zwanzig vor {nextHour}", + 45 => $"Viertel vor {nextHour}", + 50 => $"zehn vor {nextHour}", + 55 => $"fünf vor {nextHour}", + 60 => $"{nextHour} Uhr", + _ => $"{hour} Uhr {time.Minute}" //.AsWords() + }; + } + +} +#endif From c035163afc9c551491570b6a8be4d30d945aa3e9 Mon Sep 17 00:00:00 2001 From: Spoc Web <10584012+SpocWeb@users.noreply.github.com> Date: Sat, 24 Feb 2024 19:03:57 +0100 Subject: [PATCH 6/6] fixed namespaces --- .../TimeOnlyToClockNotationConvertersRegistry.cs | 2 -- .../TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs | 4 ++-- src/Humanizer/Localisation/TimeToClockNotation/German.cs | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Humanizer/Configuration/TimeOnlyToClockNotationConvertersRegistry.cs b/src/Humanizer/Configuration/TimeOnlyToClockNotationConvertersRegistry.cs index 861840197..ad6d2f0d7 100644 --- a/src/Humanizer/Configuration/TimeOnlyToClockNotationConvertersRegistry.cs +++ b/src/Humanizer/Configuration/TimeOnlyToClockNotationConvertersRegistry.cs @@ -1,5 +1,3 @@ -using Humanizer.Localisation.TimeToClockNotation; - #if NET6_0_OR_GREATER namespace Humanizer; diff --git a/src/Humanizer/Localisation/TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs b/src/Humanizer/Localisation/TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs index 7ab581c0b..c53830486 100644 --- a/src/Humanizer/Localisation/TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs +++ b/src/Humanizer/Localisation/TimeToClockNotation/DeTimeOnlyToClockNotationConverter.cs @@ -1,8 +1,8 @@ -#if NET6_0_OR_GREATER +#if NET6_0_OR_GREATER using System; -namespace Humanizer.Localisation.TimeToClockNotation; +namespace Humanizer; internal class DeTimeOnlyToClockNotationConverter : ITimeOnlyToClockNotationConverter { diff --git a/src/Humanizer/Localisation/TimeToClockNotation/German.cs b/src/Humanizer/Localisation/TimeToClockNotation/German.cs index 52c490e14..c65ef910f 100644 --- a/src/Humanizer/Localisation/TimeToClockNotation/German.cs +++ b/src/Humanizer/Localisation/TimeToClockNotation/German.cs @@ -1,9 +1,9 @@ -#if NET6_0_OR_GREATER +#if NET6_0_OR_GREATER using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -namespace Humanizer.Localisation.TimeToClockNotation; +namespace Humanizer; public static class German {