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 German TimeOnlyToClockNotation #1249

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Humanizer.All.sln.DotSettings
@@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=Localisation/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
@@ -0,0 +1,85 @@
#if NET6_0_OR_GREATER

using System;
using System.Diagnostics.CodeAnalysis;

using Xunit;

namespace Humanizer.Tests.Localisation.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
Expand Up @@ -1949,9 +1949,143 @@ namespace Humanizer
public string? Singularize(string? word, bool inputIsKnownToBePlural = true, bool skipSimpleWords = false) { }
}
public enum WordForm
{
{
Normal = 0,
Abbreviation = 1,
Eifeler = 2,
}
}
namespace Humanizer.Localisation
{
public enum DataUnit
{
Bit = 0,
Byte = 1,
Kilobyte = 2,
Megabyte = 3,
Gigabyte = 4,
Terabyte = 5,
}
public class ResourceKeys
{
public ResourceKeys() { }
public class static DateHumanize
{
public const string Never = "DateHumanize_Never";
public const string Now = "DateHumanize_Now";
public static string GetResourceKey(Humanizer.Localisation.TimeUnit timeUnit, Humanizer.Localisation.Tense timeUnitTense, int count = 1) { }
}
public class static TimeSpanHumanize
{
public static string GetResourceKey(Humanizer.Localisation.TimeUnit unit, int count = 1, bool toWords = False) { }
}
public class static TimeUnitSymbol
{
public static string GetResourceKey(Humanizer.Localisation.TimeUnit unit) { }
}
}
public class static Resources
{
public static string GetResource(string resourceKey, System.Globalization.CultureInfo culture = null) { }
}
public enum Tense
{
Future = 0,
Past = 1,
}
public enum TimeUnit
{
Millisecond = 0,
Second = 1,
Minute = 2,
Hour = 3,
Day = 4,
Week = 5,
Month = 6,
Year = 7,
}
}
namespace Humanizer.Localisation.DateToOrdinalWords
{
public interface IDateOnlyToOrdinalWordConverter
{
string Convert(System.DateOnly date);
string Convert(System.DateOnly date, Humanizer.GrammaticalCase grammaticalCase);
}
public interface IDateToOrdinalWordConverter
{
string Convert(System.DateTime date);
string Convert(System.DateTime date, Humanizer.GrammaticalCase grammaticalCase);
}
}
namespace Humanizer.Localisation.Formatters
{
public class DefaultFormatter : Humanizer.Localisation.Formatters.IFormatter
{
public DefaultFormatter(string localeCode) { }
public virtual string DataUnitHumanize(Humanizer.Localisation.DataUnit dataUnit, double count, bool toSymbol = True) { }
public virtual string DateHumanize(Humanizer.Localisation.TimeUnit timeUnit, Humanizer.Localisation.Tense timeUnitTense, int unit) { }
public virtual string DateHumanize_Never() { }
public virtual string DateHumanize_Now() { }
protected virtual string Format(string resourceKey) { }
protected virtual string Format(string resourceKey, int number, bool toWords = False) { }
protected virtual string GetResourceKey(string resourceKey, int number) { }
protected virtual string GetResourceKey(string resourceKey) { }
public virtual string TimeSpanHumanize(Humanizer.Localisation.TimeUnit timeUnit, int unit, bool toWords = False) { }
public virtual string TimeSpanHumanize_Zero() { }
public virtual string TimeUnitHumanize(Humanizer.Localisation.TimeUnit timeUnit) { }
}
public interface IFormatter
{
string DataUnitHumanize(Humanizer.Localisation.DataUnit dataUnit, double count, bool toSymbol = True);
string DateHumanize(Humanizer.Localisation.TimeUnit timeUnit, Humanizer.Localisation.Tense timeUnitTense, int unit);
string DateHumanize_Never();
string DateHumanize_Now();
string TimeSpanHumanize(Humanizer.Localisation.TimeUnit timeUnit, int unit, bool toWords = False);
string TimeSpanHumanize_Zero();
string TimeUnitHumanize(Humanizer.Localisation.TimeUnit timeUnit);
}
}
namespace Humanizer.Localisation.NumberToWords
{
public interface INumberToWordsConverter
{
string Convert(long number);
string Convert(long number, Humanizer.WordForm wordForm);
string Convert(long number, bool addAnd);
string Convert(long number, bool addAnd, Humanizer.WordForm wordForm);
string Convert(long number, Humanizer.GrammaticalGender gender, bool addAnd = True);
string Convert(long number, Humanizer.WordForm wordForm, Humanizer.GrammaticalGender gender, bool addAnd = True);
string ConvertToOrdinal(int number);
string ConvertToOrdinal(int number, Humanizer.WordForm wordForm);
string ConvertToOrdinal(int number, Humanizer.GrammaticalGender gender);
string ConvertToOrdinal(int number, Humanizer.GrammaticalGender gender, Humanizer.WordForm wordForm);
string ConvertToTuple(int number);
}
}
namespace Humanizer.Localisation.Ordinalizers
{
public interface IOrdinalizer
{
string Convert(int number, string numberString);
string Convert(int number, string numberString, Humanizer.WordForm wordForm);
string Convert(int number, string numberString, Humanizer.GrammaticalGender gender);
string Convert(int number, string numberString, Humanizer.GrammaticalGender gender, Humanizer.WordForm wordForm);
}
}
namespace Humanizer.Localisation.TimeToClockNotation
{
public class static German
{
public const string MidDay = "Mittag";
public const string MidNight = "Mitternacht";
public static readonly System.Collections.Generic.IReadOnlyList<string> 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);
}
}
@@ -1,16 +1,17 @@
#if NET6_0_OR_GREATER
#if NET6_0_OR_GREATER

namespace Humanizer;

class TimeOnlyToClockNotationConvertersRegistry : LocaliserRegistry<ITimeOnlyToClockNotationConverter>
{
public TimeOnlyToClockNotationConvertersRegistry() : base(new DefaultTimeOnlyToClockNotationConverter())
{
Register("pt-BR", new BrazilianPortugueseTimeOnlyToClockNotationConverter());
Register("fr", new FrTimeOnlyToClockNotationConverter());
Register("es", new EsTimeOnlyToClockNotationConverter());
Register("lb", new LbTimeOnlyToClockNotationConverter());
public TimeOnlyToClockNotationConvertersRegistry() : base(new DefaultTimeOnlyToClockNotationConverter())
{
Register("pt-BR", new BrazilianPortugueseTimeOnlyToClockNotationConverter());
Register("fr", new FrTimeOnlyToClockNotationConverter());
Register("es", new EsTimeOnlyToClockNotationConverter());
Register("lb", new LbTimeOnlyToClockNotationConverter());
Register("de", new DeTimeOnlyToClockNotationConverter());
}
}
}

#endif
33 changes: 13 additions & 20 deletions src/Humanizer/Localisation/Ordinalizers/EnglishOrdinalizer.cs
Expand Up @@ -2,28 +2,21 @@

class EnglishOrdinalizer : DefaultOrdinalizer
{
public override string Convert(int number, string numberString)
{
var nMod100 = number % 100;

if (nMod100 is >= 11 and <= 20)
{
return numberString + "th";
}

switch (number % 10)
public override string Convert(int number, string numberString)
{
case 1:
return numberString + "st";
var nMod100 = number % 100;

case 2:
return numberString + "nd";

case 3:
return numberString + "rd";

default:
if (nMod100 is >= 11 and <= 20)
{
return numberString + "th";
}

return (number % 10) switch
{
1 => numberString + "st",
2 => numberString + "nd",
3 => numberString + "rd",
_ => numberString + "th"
};
}
}
}
@@ -0,0 +1,31 @@
#if NET6_0_OR_GREATER

using System;

namespace Humanizer;

internal class DeTimeOnlyToClockNotationConverter : ITimeOnlyToClockNotationConverter
{
/// <summary> Switch to output Digits as Words </summary>
public bool AsWords;

/// <summary> Used to pre-pend, append or omit the Quarter of the Day </summary>
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.Value switch
{
false => ret + ' ' + time.GetDayQuarterGermanGenitive(),
true => time.GetDayQuarterGermanGenitive() + ' ' + ret
};
}
}

#endif