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

Fix DateOnly, TimeOnly & DateTime issues in French #1150

Merged
merged 3 commits into from
Dec 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using Xunit;

namespace Humanizer.Tests.Localisation.fr
{
[UseCulture("fr")]
public class DateToOrdinalWordsTests
{
[Fact]
public void OrdinalizeString()
{
Assert.Equal("1er janvier 2015", new DateTime(2015, 1, 1).ToOrdinalWords());
Assert.Equal("2 mars 2020", new DateTime(2020, 3, 2).ToOrdinalWords());
Assert.Equal("31 octobre 2021", new DateTime(2021, 10, 31).ToOrdinalWords());
}

#if NET6_0_OR_GREATER
[Fact]
public void OrdinalizeDateOnlyString()
{
Assert.Equal("1er janvier 2015", new DateOnly(2015, 1, 1).ToOrdinalWords());
Assert.Equal("2 mars 2020", new DateOnly(2020, 3, 2).ToOrdinalWords());
Assert.Equal("31 octobre 2021", new DateOnly(2021, 10, 31).ToOrdinalWords());
}
#endif
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#if NET6_0_OR_GREATER

using System;
using Xunit;

namespace Humanizer.Tests.Localisation.fr
{
[UseCulture("fr")]
public class TimeOnlyHumanizeTests
{
[Fact]
public void DefaultStrategy_SameTime()
{
var inputTime = new TimeOnly(13, 07, 05);
var baseTime = new TimeOnly(13, 07, 05);

const string expectedResult = "maintenant";
var actualResult = inputTime.Humanize(baseTime);

Assert.Equal(expectedResult, actualResult);
}

[Fact]
public void DefaultStrategy_HoursApart()
{
var inputTime = new TimeOnly(13, 08, 05);
var baseTime = new TimeOnly(1, 08, 05);

const string expectedResult = "dans 12 heures";
var actualResult = inputTime.Humanize(baseTime);

Assert.Equal(expectedResult, actualResult);
}

[Fact]
public void DefaultStrategy_HoursAgo()
{
var inputTime = new TimeOnly(13, 07, 02);
var baseTime = new TimeOnly(17, 07, 05);

const string expectedResult = "il y a 4 heures";
var actualResult = inputTime.Humanize(baseTime);

Assert.Equal(expectedResult, actualResult);
}

[Fact]
public void PrecisionStrategy_NextDay()
{
var inputTime = new TimeOnly(18, 10, 49);
var baseTime = new TimeOnly(13, 07, 04);

const string expectedResult = "dans 5 heures";
var actualResult = inputTime.Humanize(baseTime);

Assert.Equal(expectedResult, actualResult);
}


[Fact]
public void Never()
{
TimeOnly? never = null;
Assert.Equal("jamais", never.Humanize());
}

[Fact]
public void Nullable_ExpectSame()
{
TimeOnly? never = new TimeOnly(23, 12, 7);
Assert.Equal(never.Value.Humanize(), never.Humanize());
}
}
}

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

using System;
using Xunit;

namespace Humanizer.Tests.Localisation.fr
{
[UseCulture("fr")]
public class TimeToClockNotationTests
{
[Theory]
[InlineData(00, 00, "minuit")]
[InlineData(00, 07, "minuit sept")]
[InlineData(01, 11, "une heure onze")]
[InlineData(04, 00, "quatre heures")]
[InlineData(05, 01, "cinq heures une")]
[InlineData(06, 05, "six heures cinq")]
[InlineData(07, 10, "sept heures dix")]
[InlineData(08, 15, "huit heures quinze")]
[InlineData(09, 20, "neuf heures vingt")]
[InlineData(10, 25, "dix heures vingt-cinq")]
[InlineData(11, 30, "onze heures trente")]
[InlineData(12, 00, "midi")]
[InlineData(12, 38, "midi trente-huit")]
[InlineData(15, 35, "quinze heures trente-cinq")]
[InlineData(16, 40, "seize heures quarante")]
[InlineData(17, 45, "dix-sept heures quarante-cinq")]
[InlineData(18, 50, "dix-huit heures cinquante")]
[InlineData(19, 55, "dix-neuf heures cinquante-cinq")]
[InlineData(20, 59, "vingt heures cinquante-neuf")]
public void ConvertToClockNotationTimeOnlyString(int hours, int minutes, string expectedResult)
{
var actualResult = new TimeOnly(hours, minutes).ToClockNotation();
Assert.Equal(expectedResult, actualResult);
}

[Theory]
[InlineData(00, 00, "minuit")]
[InlineData(00, 07, "minuit cinq")]
[InlineData(01, 11, "une heure dix")]
[InlineData(04, 00, "quatre heures")]
[InlineData(05, 01, "cinq heures")]
[InlineData(06, 05, "six heures cinq")]
[InlineData(07, 10, "sept heures dix")]
[InlineData(08, 15, "huit heures quinze")]
[InlineData(09, 20, "neuf heures vingt")]
[InlineData(10, 25, "dix heures vingt-cinq")]
[InlineData(11, 30, "onze heures trente")]
[InlineData(12, 00, "midi")]
[InlineData(12, 38, "midi quarante")]
[InlineData(13, 23, "treize heures vingt-cinq")]
[InlineData(14, 32, "quatorze heures trente")]
[InlineData(15, 35, "quinze heures trente-cinq")]
[InlineData(16, 40, "seize heures quarante")]
[InlineData(17, 45, "dix-sept heures quarante-cinq")]
[InlineData(18, 50, "dix-huit heures cinquante")]
[InlineData(19, 55, "dix-neuf heures cinquante-cinq")]
louis-z marked this conversation as resolved.
Show resolved Hide resolved
[InlineData(20, 59, "vingt et une heures")]
public void ConvertToRoundedClockNotationTimeOnlyString(int hours, int minutes, string expectedResult)
{
var actualResult = new TimeOnly(hours, minutes).ToClockNotation(ClockNotationRounding.NearestFiveMinutes);
Assert.Equal(expectedResult, actualResult);
}
}
}

#endif
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
#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());
Register("fr", new FrDateOnlyToOrdinalWordsConverter());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using Humanizer.Localisation.DateToOrdinalWords;

namespace Humanizer.Configuration
{
internal class DateToOrdinalWordsConverterRegistry : LocaliserRegistry<IDateToOrdinalWordConverter>
{
public DateToOrdinalWordsConverterRegistry() : base(new DefaultDateToOrdinalWordConverter())
{
Register("en-UK", new DefaultDateToOrdinalWordConverter());
Register("de", new DefaultDateToOrdinalWordConverter());
Register("en-US", new UsDateToOrdinalWordsConverter());
Register("fr", new FrDateToOrdinalWordsConverter());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ internal class TimeOnlyToClockNotationConvertersRegistry : LocaliserRegistry<ITi
public TimeOnlyToClockNotationConvertersRegistry() : base(new DefaultTimeOnlyToClockNotationConverter())
{
Register("pt-BR", new BrazilianPortugueseTimeOnlyToClockNotationConverter());
Register("fr", new FrTimeOnlyToClockNotationConverter());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#if NET6_0_OR_GREATER
using System;

namespace Humanizer.Localisation.DateToOrdinalWords
{
internal class FrDateOnlyToOrdinalWordsConverter : DefaultDateOnlyToOrdinalWordConverter
{
public override string Convert(DateOnly date)
{
var day = date.Day > 1 ? date.Day.ToString() : date.Day.Ordinalize();
return day + date.ToString(" MMMM yyyy");
}
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;

namespace Humanizer.Localisation.DateToOrdinalWords
{
internal class FrDateToOrdinalWordsConverter : DefaultDateToOrdinalWordConverter
{
public override string Convert(DateTime date)
{
var day = date.Day > 1 ? date.Day.ToString() : date.Day.Ordinalize();
return day + date.ToString(" MMMM yyyy");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#if NET6_0_OR_GREATER

using System;
using Humanizer;

namespace Humanizer.Localisation.TimeToClockNotation
{
internal class FrTimeOnlyToClockNotationConverter : ITimeOnlyToClockNotationConverter
{
public virtual string Convert(TimeOnly time, ClockNotationRounding roundToNearestFive)
{
var normalizedMinutes = (int)(roundToNearestFive == ClockNotationRounding.NearestFiveMinutes
? 5 * Math.Round(time.Minute / 5.0)
: time.Minute);

return normalizedMinutes switch
{
00 => GetHourExpression(time.Hour),
60 => GetHourExpression(time.Hour + 1),
_ => $"{GetHourExpression(time.Hour)} {normalizedMinutes.ToWords(GrammaticalGender.Feminine)}"
};

static string GetHourExpression(int hour)
{
return hour switch
{
0 => "minuit",
12 => "midi",
_ => hour.ToWords(GrammaticalGender.Feminine) + (hour > 1 ? " heures" : " heure")
};
}
}
}
}

#endif