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

French translations #991

Open
wants to merge 3 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
11 changes: 11 additions & 0 deletions readme.md
Expand Up @@ -462,6 +462,17 @@ If words are preferred to numbers, a `toWords: true` parameter can be set to con
TimeSpan.FromMilliseconds(1299630020).Humanize(3, toWords: true) => "two weeks, one day, one hour"
````

If you would prefer and abbreviation to the complete Time Unit, a `abbreviate: true` parameter can be set to convert time units to the following abbreviations:
- Milliseconds: `ms`,
- Seconds: `s`,
- Minutes: `m`,
- Hours: `h`,
- Days: `d`,
- Weeks: `W`,
- Months: `M`,
- Years: `Y`,

Note that anything bigger then 'Days' will be capitalized.
### <a id="humanize-collections">Humanize Collections</a>
You can call `Humanize` on any `IEnumerable` to get a nicely formatted string representing the objects in the collection. By default `ToString()` will be called on each item to get its representation but a formatting function may be passed to `Humanize` instead. Additionally, a default separator is provided ("and" in English), but a different separator may be passed into `Humanize`.

Expand Down
9 changes: 9 additions & 0 deletions src/Humanizer.Tests.Shared/TimeSpanHumanizeTests.cs
Expand Up @@ -227,6 +227,15 @@ public void TimeSpanWithMinTimeUnit(long ms, string expected, TimeUnit minUnit,
Assert.Equal(expected, actual);
}

[Theory]
[InlineData(34390862500, "1 Y, 1 M, 2 d, 1 h, 1 m, 2 s, 500 ms", TimeUnit.Millisecond)]
[InlineData(604800000, "1 W", TimeUnit.Millisecond)]
public void TimeSpanWithAllUnitsAbb(long ms, string expected, TimeUnit minUnit)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The minUnit argument is not used here.

{
var actual = TimeSpan.FromMilliseconds(ms).Humanize(7, maxUnit: TimeUnit.Year,toWords: false, abbreviated: true);
Assert.Equal(expected, actual);
}

[Theory]
[InlineData(0, 3, "no time", true)]
[InlineData(0, 2, "no time", true)]
Expand Down
1 change: 1 addition & 0 deletions src/Humanizer.Tests/Humanizer.Tests.csproj
Expand Up @@ -9,6 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="1.3.0" PrivateAssets="all" />
<PackageReference Include="System.Globalization" Version="4.3.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
Expand Down
5 changes: 4 additions & 1 deletion src/Humanizer/Humanizer.csproj
Expand Up @@ -12,5 +12,8 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Humanizer.snk</AssemblyOriginatorKeyFile>
<DebugType Condition=" '$(BuildingForLiveUnitTesting)' != 'true' ">embedded</DebugType>
</PropertyGroup>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Globalization" Version="4.3.0" />
</ItemGroup>
</Project>
10 changes: 5 additions & 5 deletions src/Humanizer/Localisation/Formatters/DefaultFormatter.cs
Expand Up @@ -66,9 +66,9 @@ public virtual string TimeSpanHumanize_Zero()
/// <param name="toWords"></param>
/// <returns></returns>
/// <exception cref="System.ArgumentOutOfRangeException">Is thrown when timeUnit is larger than TimeUnit.Week</exception>
public virtual string TimeSpanHumanize(TimeUnit timeUnit, int unit, bool toWords = false)
public virtual string TimeSpanHumanize(TimeUnit timeUnit, int unit, bool toWords = false, bool abbreviated = false)
{
return GetResourceForTimeSpan(timeUnit, unit, toWords);
return GetResourceForTimeSpan(timeUnit, unit, toWords, abbreviated);
}

private string GetResourceForDate(TimeUnit unit, Tense timeUnitTense, int count)
Expand All @@ -77,10 +77,10 @@ private string GetResourceForDate(TimeUnit unit, Tense timeUnitTense, int count)
return count == 1 ? Format(resourceKey) : Format(resourceKey, count);
}

private string GetResourceForTimeSpan(TimeUnit unit, int count, bool toWords = false)
private string GetResourceForTimeSpan(TimeUnit unit, int count, bool toWords = false, bool abbreviated = false)
{
var resourceKey = ResourceKeys.TimeSpanHumanize.GetResourceKey(unit, count, toWords);
return count == 1 ? Format(resourceKey + (toWords ? "_Words" : "")) : Format(resourceKey, count, toWords);
var resourceKey = ResourceKeys.TimeSpanHumanize.GetResourceKey(unit, count, toWords, abbreviated);
return count == 1 && !abbreviated ? Format(resourceKey + (toWords ? "_Words" : "")) : Format(resourceKey, count, toWords);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Humanizer/Localisation/Formatters/IFormatter.cs
Expand Up @@ -41,6 +41,6 @@ public interface IFormatter
/// <param name="unit"></param>
/// <param name="toWords"></param>
/// <returns></returns>
string TimeSpanHumanize(TimeUnit timeUnit, int unit, bool toWords = false);
string TimeSpanHumanize(TimeUnit timeUnit, int unit, bool toWords = false, bool abbreviate = false);
}
}
Expand Up @@ -43,7 +43,7 @@ public PolishNumberToWordsConverter(CultureInfo culture)
_culture = culture;
}

public override string Convert(long input, GrammaticalGender gender)
public string Convert(long input, GrammaticalGender gender)
{
if (input == 0)
{
Expand All @@ -55,7 +55,12 @@ public override string Convert(long input, GrammaticalGender gender)

return string.Join(" ", parts);
}


public override string Convert(long number, GrammaticalGender gender, bool addAnd = true)
{
return Convert(number, gender);
}

public override string ConvertToOrdinal(int number, GrammaticalGender gender)
{
return number.ToString(_culture);
Expand Down
1 change: 1 addition & 0 deletions src/Humanizer/Localisation/ResourceKeys.Common.cs
Expand Up @@ -9,6 +9,7 @@ public partial class ResourceKeys
{
private const string Single = "Single";
private const string Multiple = "Multiple";
private const string Abbreviate = "Abb";

private static void ValidateRange(int count)
{
Expand Down
5 changes: 4 additions & 1 deletion src/Humanizer/Localisation/ResourceKeys.TimeSpanHumanize.cs
Expand Up @@ -20,8 +20,9 @@ public static class TimeSpanHumanize
/// <param name="unit">Time unit, <see cref="TimeUnit"/>.</param>
/// <param name="count">Number of units, default is One.</param>
/// <param name="toWords">Result to words, default is false.</param>
/// <param name="abbreviate">Resulting units abbreviated => seconds: s. Default false</param>
/// <returns>Resource key, like TimeSpanHumanize_SingleMinute</returns>
public static string GetResourceKey(TimeUnit unit, int count = 1, bool toWords = false)
public static string GetResourceKey(TimeUnit unit, int count = 1, bool toWords = false, bool abbreviate = false)
{
ValidateRange(count);

Expand All @@ -30,6 +31,8 @@ public static string GetResourceKey(TimeUnit unit, int count = 1, bool toWords =
return Zero;
}

if (abbreviate) return TimeSpanFormat.FormatWith(Abbreviate, unit, "");

return TimeSpanFormat.FormatWith(count == 1 ? Single : Multiple, unit, count == 1 ? "" : "s");
}
}
Expand Down
72 changes: 72 additions & 0 deletions src/Humanizer/Properties/Resources.fr.resx
Expand Up @@ -276,4 +276,76 @@
<data name="TimeSpanHumanize_MultipleMilliseconds_Singular" xml:space="preserve">
<value>{0} milliseconde</value>
</data>
<data name="TimeSpanHumanize_AbbDay" xml:space="preserve">
<value>{0} j</value>
</data>
<data name="TimeSpanHumanize_AbbHour" xml:space="preserve">
<value>{0} h</value>
</data>
<data name="TimeSpanHumanize_AbbMillisecond" xml:space="preserve">
<value>{0} ms</value>
</data>
<data name="TimeSpanHumanize_AbbMinute" xml:space="preserve">
<value>{0} m</value>
</data>
<data name="TimeSpanHumanize_AbbMonth" xml:space="preserve">
<value>{0} M</value>
</data>
<data name="TimeSpanHumanize_AbbSecond" xml:space="preserve">
<value>{0} s</value>
</data>
<data name="TimeSpanHumanize_AbbWeek" xml:space="preserve">
<value>{0} W</value>
</data>
<data name="TimeSpanHumanize_AbbYear" xml:space="preserve">
<value>{0} Y</value>
</data>
<data name="TimeSpanHumanize_SingleDay_Words" xml:space="preserve">
<value>un jour</value>
</data>
<data name="TimeSpanHumanize_SingleHour_Words" xml:space="preserve">
<value>une heure</value>
</data>
<data name="TimeSpanHumanize_SingleMillisecond_Words" xml:space="preserve">
<value>une milliseconde</value>
</data>
<data name="TimeSpanHumanize_SingleMinute_Words" xml:space="preserve">
<value>une minute</value>
</data>
<data name="TimeSpanHumanize_SingleMonth_Words" xml:space="preserve">
<value>un mois</value>
</data>
<data name="TimeSpanHumanize_SingleSecond_Words" xml:space="preserve">
<value>une seconde</value>
</data>
<data name="TimeSpanHumanize_SingleWeek_Words" xml:space="preserve">
<value>une semaine</value>
</data>
<data name="TimeSpanHumanize_SingleYear_Words" xml:space="preserve">
<value>un an</value>
</data>
<data name="TimeSpanHumanize_MultipleWeeks_Plural" xml:space="preserve">
<value>{0} semaines</value>
</data>
<data name="TimeSpanHumanize_MultipleDays_Plural" xml:space="preserve">
<value>{0} jours</value>
</data>
<data name="TimeSpanHumanize_MultipleHours_Plural" xml:space="preserve">
<value>{0} heures</value>
</data>
<data name="TimeSpanHumanize_MultipleMilliseconds_Plural" xml:space="preserve">
<value>{0} millisecondes</value>
</data>
<data name="TimeSpanHumanize_MultipleMinutes_Plural" xml:space="preserve">
<value>{0} minutes</value>
</data>
<data name="TimeSpanHumanize_MultipleMonths_Plural" xml:space="preserve">
<value>{0} mois</value>
</data>
<data name="TimeSpanHumanize_MultipleSeconds_Plural" xml:space="preserve">
<value>{0} secondes</value>
</data>
<data name="TimeSpanHumanize_MultipleYears_Plural" xml:space="preserve">
<value>{0} ans</value>
</data>
</root>
24 changes: 24 additions & 0 deletions src/Humanizer/Properties/Resources.resx
Expand Up @@ -675,4 +675,28 @@
<data name="NNW_Short" xml:space="preserve">
<value>NNW</value>
</data>
<data name="TimeSpanHumanize_AbbSecond" xml:space="preserve">
<value>{0} s</value>
</data>
<data name="TimeSpanHumanize_AbbDay" xml:space="preserve">
<value>{0} d</value>
</data>
<data name="TimeSpanHumanize_AbbHour" xml:space="preserve">
<value>{0} h</value>
</data>
<data name="TimeSpanHumanize_AbbMillisecond" xml:space="preserve">
<value>{0} ms</value>
</data>
<data name="TimeSpanHumanize_AbbMinute" xml:space="preserve">
<value>{0} m</value>
</data>
<data name="TimeSpanHumanize_AbbWeek" xml:space="preserve">
<value>{0} W</value>
</data>
<data name="TimeSpanHumanize_AbbMonth" xml:space="preserve">
<value>{0} M</value>
</data>
<data name="TimeSpanHumanize_AbbYear" xml:space="preserve">
<value>{0} Y</value>
</data>
</root>
20 changes: 10 additions & 10 deletions src/Humanizer/TimeSpanHumanizeExtensions.cs
Expand Up @@ -28,9 +28,9 @@ public static class TimeSpanHumanizeExtensions
/// <param name="collectionSeparator">The separator to use when combining humanized time parts. If null, the default collection formatter for the current culture is used.</param>
/// <param name="toWords">Uses words instead of numbers if true. E.g. one day.</param>
/// <returns></returns>
public static string Humanize(this TimeSpan timeSpan, int precision = 1, CultureInfo culture = null, TimeUnit maxUnit = TimeUnit.Week, TimeUnit minUnit = TimeUnit.Millisecond, string collectionSeparator = ", ", bool toWords = false)
public static string Humanize(this TimeSpan timeSpan, int precision = 1, CultureInfo culture = null, TimeUnit maxUnit = TimeUnit.Week, TimeUnit minUnit = TimeUnit.Millisecond, string collectionSeparator = ", ", bool toWords = false, bool abbreviated = false)
{
return Humanize(timeSpan, precision, false, culture, maxUnit, minUnit, collectionSeparator, toWords);
return Humanize(timeSpan, precision, false, culture, maxUnit, minUnit, collectionSeparator, toWords, abbreviated);
}

/// <summary>
Expand All @@ -45,15 +45,15 @@ public static string Humanize(this TimeSpan timeSpan, int precision = 1, Culture
/// <param name="collectionSeparator">The separator to use when combining humanized time parts. If null, the default collection formatter for the current culture is used.</param>
/// <param name="toWords">Uses words instead of numbers if true. E.g. one day.</param>
/// <returns></returns>
public static string Humanize(this TimeSpan timeSpan, int precision, bool countEmptyUnits, CultureInfo culture = null, TimeUnit maxUnit = TimeUnit.Week, TimeUnit minUnit = TimeUnit.Millisecond, string collectionSeparator = ", ", bool toWords = false)
public static string Humanize(this TimeSpan timeSpan, int precision, bool countEmptyUnits, CultureInfo culture = null, TimeUnit maxUnit = TimeUnit.Week, TimeUnit minUnit = TimeUnit.Millisecond, string collectionSeparator = ", ", bool toWords = false, bool abbreviated = false)
{
var timeParts = CreateTheTimePartsWithUpperAndLowerLimits(timeSpan, culture, maxUnit, minUnit, toWords);
var timeParts = CreateTheTimePartsWithUpperAndLowerLimits(timeSpan, culture, maxUnit, minUnit, toWords, abbreviated);
timeParts = SetPrecisionOfTimeSpan(timeParts, precision, countEmptyUnits);

return ConcatenateTimeSpanParts(timeParts, culture, collectionSeparator);
}

private static IEnumerable<string> CreateTheTimePartsWithUpperAndLowerLimits(TimeSpan timespan, CultureInfo culture, TimeUnit maxUnit, TimeUnit minUnit, bool toWords = false)
private static IEnumerable<string> CreateTheTimePartsWithUpperAndLowerLimits(TimeSpan timespan, CultureInfo culture, TimeUnit maxUnit, TimeUnit minUnit, bool toWords = false, bool abbreviated = false)
{
var cultureFormatter = Configurator.GetFormatter(culture);
var firstValueFound = false;
Expand All @@ -62,7 +62,7 @@ private static IEnumerable<string> CreateTheTimePartsWithUpperAndLowerLimits(Tim

foreach (var timeUnitType in timeUnitsEnumTypes)
{
var timepart = GetTimeUnitPart(timeUnitType,timespan, maxUnit, minUnit, cultureFormatter, toWords);
var timepart = GetTimeUnitPart(timeUnitType,timespan, maxUnit, minUnit, cultureFormatter, toWords, abbreviated);

if (timepart != null || firstValueFound)
{
Expand All @@ -85,12 +85,12 @@ private static IEnumerable<TimeUnit> GetEnumTypesForTimeUnit()
return enumTypeEnumerator.Reverse();
}

private static string GetTimeUnitPart(TimeUnit timeUnitToGet, TimeSpan timespan, TimeUnit maximumTimeUnit, TimeUnit minimumTimeUnit, IFormatter cultureFormatter, bool toWords = false)
private static string GetTimeUnitPart(TimeUnit timeUnitToGet, TimeSpan timespan, TimeUnit maximumTimeUnit, TimeUnit minimumTimeUnit, IFormatter cultureFormatter, bool toWords = false, bool abbreviated = false)
{
if (timeUnitToGet <= maximumTimeUnit && timeUnitToGet >= minimumTimeUnit)
{
var numberOfTimeUnits = GetTimeUnitNumericalValue(timeUnitToGet, timespan, maximumTimeUnit);
return BuildFormatTimePart(cultureFormatter, timeUnitToGet, numberOfTimeUnits, toWords);
return BuildFormatTimePart(cultureFormatter, timeUnitToGet, numberOfTimeUnits, toWords, abbreviated);
}
return null;
}
Expand Down Expand Up @@ -179,11 +179,11 @@ private static int GetNormalCaseTimeAsInteger(int timeNumberOfUnits, double tota
return timeNumberOfUnits;
}

private static string BuildFormatTimePart(IFormatter cultureFormatter, TimeUnit timeUnitType, int amountOfTimeUnits, bool toWords = false)
private static string BuildFormatTimePart(IFormatter cultureFormatter, TimeUnit timeUnitType, int amountOfTimeUnits, bool toWords = false, bool abbreviated = false)
{
// Always use positive units to account for negative timespans
return amountOfTimeUnits != 0
? cultureFormatter.TimeSpanHumanize(timeUnitType, Math.Abs(amountOfTimeUnits), toWords)
? cultureFormatter.TimeSpanHumanize(timeUnitType, Math.Abs(amountOfTimeUnits), toWords, abbreviated)
: null;
}

Expand Down