Skip to content

Commit

Permalink
Add support for DateOnly to ordinal words
Browse files Browse the repository at this point in the history
  • Loading branch information
clairernovotny committed Jun 7, 2021
1 parent f2de33d commit b2491d8
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,13 @@ public void OrdinalizeString()
{
Assert.Equal("1. Januar 2015", new DateTime(2015, 1, 1).ToOrdinalWords());
}

#if NET6_0_OR_GREATER
[Fact]
public void OrdinalizeDateOnlyString()
{
Assert.Equal("1. Januar 2015", new DateOnly(2015, 1, 1).ToOrdinalWords());
}
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,21 @@ public void OrdinalizeStringUs()
{
Assert.Equal("January 1st, 2015", new DateTime(2015, 1, 1).ToOrdinalWords());
}

#if NET6_0_OR_GREATER
[UseCulture("en-GB")]
[Fact]
public void OrdinalizeDateOnlyStringGb()
{
Assert.Equal("1st January 2015", new DateOnly(2015, 1, 1).ToOrdinalWords());
}

[UseCulture("en-US")]
[Fact]
public void OrdinalizeDateOnlyStringUs()
{
Assert.Equal("January 1st, 2015", new DateOnly(2015, 1, 1).ToOrdinalWords());
}
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ namespace Humanizer
{
public static string ToOrdinalWords(this System.DateTime input) { }
public static string ToOrdinalWords(this System.DateTime input, Humanizer.GrammaticalCase grammaticalCase) { }
public static string ToOrdinalWords(this System.DateOnly input) { }
public static string ToOrdinalWords(this System.DateOnly input, Humanizer.GrammaticalCase grammaticalCase) { }
}
public class static EnglishArticle
{
Expand Down Expand Up @@ -1717,6 +1719,7 @@ namespace Humanizer.Configuration
{
public static Humanizer.Configuration.LocaliserRegistry<Humanizer.Localisation.CollectionFormatters.ICollectionFormatter> CollectionFormatters { get; }
public static Humanizer.DateTimeHumanizeStrategy.IDateOnlyHumanizeStrategy DateOnlyHumanizeStrategy { get; set; }
public static Humanizer.Configuration.LocaliserRegistry<Humanizer.Localisation.DateToOrdinalWords.IDateOnlyToOrdinalWordConverter> DateOnlyToOrdinalWordsConverters { get; }
public static Humanizer.DateTimeHumanizeStrategy.IDateTimeHumanizeStrategy DateTimeHumanizeStrategy { get; set; }
public static Humanizer.DateTimeHumanizeStrategy.IDateTimeOffsetHumanizeStrategy DateTimeOffsetHumanizeStrategy { get; set; }
public static Humanizer.Configuration.LocaliserRegistry<Humanizer.Localisation.DateToOrdinalWords.IDateToOrdinalWordConverter> DateToOrdinalWordsConverters { get; }
Expand Down Expand Up @@ -1872,6 +1875,11 @@ namespace Humanizer.Localisation
}
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);
Expand Down
24 changes: 24 additions & 0 deletions src/Humanizer/Configuration/Configurator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,17 @@ public static LocaliserRegistry<IDateToOrdinalWordConverter> DateToOrdinalWordsC
get { return _dateToOrdinalWordConverters; }
}

#if NET6_0_OR_GREATER
private static readonly LocaliserRegistry<IDateOnlyToOrdinalWordConverter> _dateOnlyToOrdinalWordConverters = new DateOnlyToOrdinalWordsConverterRegistry();
/// <summary>
/// A registry of ordinalizers used to localise Ordinalize method
/// </summary>
public static LocaliserRegistry<IDateOnlyToOrdinalWordConverter> DateOnlyToOrdinalWordsConverters
{
get { return _dateOnlyToOrdinalWordConverters; }
}
#endif

internal static ICollectionFormatter CollectionFormatter
{
get
Expand Down Expand Up @@ -109,6 +120,19 @@ internal static IDateToOrdinalWordConverter DateToOrdinalWordsConverter
}
}

#if NET6_0_OR_GREATER
/// <summary>
/// The ordinalizer to be used
/// </summary>
internal static IDateOnlyToOrdinalWordConverter DateOnlyToOrdinalWordsConverter
{
get
{
return DateOnlyToOrdinalWordsConverters.ResolveForUiCulture();
}
}
#endif

private static IDateTimeHumanizeStrategy _dateTimeHumanizeStrategy = new DefaultDateTimeHumanizeStrategy();
/// <summary>
/// The strategy to be used for DateTime.Humanize
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#if NET6_0_OR_GREATER

using Humanizer.Localisation.DateToOrdinalWords;
namespace Humanizer.Configuration
{
internal class DateOnlyToOrdinalWordsConverterRegistry : LocaliserRegistry<IDateOnlyToOrdinalWordConverter>
{
public DateOnlyToOrdinalWordsConverterRegistry() : base(new DefaultDateOnlyToOrdinalWordConverter())
{
Register("en-UK", new DefaultDateOnlyToOrdinalWordConverter());
Register("de", new DefaultDateOnlyToOrdinalWordConverter());
Register("en-US", new UsDateOnlyToOrdinalWordsConverter());
}
}
}
#endif
4 changes: 2 additions & 2 deletions src/Humanizer/DateHumanizeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public static string Humanize(this DateOnly? input, DateOnly? dateToCompareAgain
/// Turns the current or provided time into a human readable sentence
/// </summary>
/// <param name="input">The date to be humanized</param>
/// <param name="useUtc">If <paramref name="dateToCompareAgainst"/> is null, used to determine if the current time is UTC or local. Defaults to UTC.</param>
/// <param name="useUtc">If <paramref name="timeToCompareAgainst"/> is null, used to determine if the current time is UTC or local. Defaults to UTC.</param>
/// <param name="timeToCompareAgainst">Date to compare the input against. If null, current date is used as base</param>
/// <param name="culture">Culture to use. If null, current thread's UI culture is used.</param>
/// <returns>distance of time in words</returns>
Expand All @@ -132,7 +132,7 @@ public static string Humanize(this TimeOnly input, TimeOnly? timeToCompareAgains
/// Turns the current or provided time into a human readable sentence, overload for the nullable TimeOnly, returning 'never' in case null
/// </summary>
/// <param name="input">The date to be humanized</param>
/// <param name="useUtc">If <paramref name="dateToCompareAgainst"/> is null, used to determine if the current time is UTC or local. Defaults to UTC.</param>
/// <param name="useUtc">If <paramref name="timeToCompareAgainst"/> is null, used to determine if the current time is UTC or local. Defaults to UTC.</param>
/// <param name="timeToCompareAgainst">Time to compare the input against. If null, current date is used as base</param>
/// <param name="culture">Culture to use. If null, current thread's UI culture is used.</param>
/// <returns>distance of time in words</returns>
Expand Down
24 changes: 23 additions & 1 deletion src/Humanizer/DateToOrdinalWordsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,27 @@ public static string ToOrdinalWords(this DateTime input, GrammaticalCase grammat
{
return Configurator.DateToOrdinalWordsConverter.Convert(input, grammaticalCase);
}

#if NET6_0_OR_GREATER
/// <summary>
/// Turns the provided date into ordinal words
/// </summary>
/// <param name="input">The date to be made into ordinal words</param>
/// <returns>The date in ordinal words</returns>
public static string ToOrdinalWords(this DateOnly input)
{
return Configurator.DateOnlyToOrdinalWordsConverter.Convert(input);
}
/// <summary>
/// Turns the provided date into ordinal words
/// </summary>
/// <param name="input">The date to be made into ordinal words</param>
/// <param name="grammaticalCase">The grammatical case to use for output words</param>
/// <returns>The date in ordinal words</returns>
public static string ToOrdinalWords(this DateOnly input, GrammaticalCase grammaticalCase)
{
return Configurator.DateOnlyToOrdinalWordsConverter.Convert(input, grammaticalCase);
}
#endif
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#if NET6_0_OR_GREATER

using System;

namespace Humanizer.Localisation.DateToOrdinalWords
{
internal class DefaultDateOnlyToOrdinalWordConverter : IDateOnlyToOrdinalWordConverter
{

public virtual string Convert(DateOnly date)
{
return date.Day.Ordinalize() + date.ToString(" MMMM yyyy");
}

public virtual string Convert(DateOnly date, GrammaticalCase grammaticalCase)
{
return Convert(date);
}

}
}

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#if NET6_0_OR_GREATER

using System;

namespace Humanizer.Localisation.DateToOrdinalWords
{
/// <summary>
/// The interface used to localise the ToOrdinalWords method.
/// </summary>
public interface IDateOnlyToOrdinalWordConverter
{
/// <summary>
/// Converts the date to Ordinal Words
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
string Convert(DateOnly date);

/// <summary>
/// Converts the date to Ordinal Words using the provided grammatical case
/// </summary>
/// <param name="date"></param>
/// <param name="grammaticalCase"></param>
/// <returns></returns>
string Convert(DateOnly date, GrammaticalCase grammaticalCase);
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#if NET6_0_OR_GREATER
using System;

namespace Humanizer.Localisation.DateToOrdinalWords
{
internal class UsDateOnlyToOrdinalWordsConverter : DefaultDateOnlyToOrdinalWordConverter
{
public override string Convert(DateOnly date)
{
return date.ToString("MMMM ") + date.Day.Ordinalize() + date.ToString(", yyyy");
}
}
}
#endif

0 comments on commit b2491d8

Please sign in to comment.