Skip to content

Commit

Permalink
Merge pull request #1106 from hangy/timeunit-humanize
Browse files Browse the repository at this point in the history
  • Loading branch information
clairernovotny committed Oct 27, 2021
2 parents 938e1e4 + 18138ed commit bc1a9b7
Show file tree
Hide file tree
Showing 11 changed files with 190 additions and 0 deletions.
13 changes: 13 additions & 0 deletions readme.md
Expand Up @@ -44,6 +44,7 @@ Humanizer meets all your .NET needs for manipulating and displaying strings, enu
- [ByteSize](#bytesize)
- [Heading to words](#heading-to-words)
- [Tupleize](#tupleize)
- [Time unit to symbol](#timeunit-to-symbol)
- [Mix this into your framework to simplify your life](#mix-this-into-your-framework-to-simplify-your-life) -
- [How to contribute?](#how-to-contribute)
- [Continuous Integration from AppVeyor](#continuous-integration)
Expand Down Expand Up @@ -1109,6 +1110,18 @@ Humanizer can change whole numbers into their 'tuple' using `Tupleize`. For exa

The numbers 1-10, 100 and 1000 will be converted into a 'named' tuple (i.e. "single", "double" etc.). Any other number "n" will be converted to "n-tuple".

### <a id="timeunit-to-symbol">Time unit to symbol</a>
Humanizer can translate time units to their symbols:

```C#
TimeUnit.Day.ToSymbol();
// d
TimeUnit.Week.ToSymbol();
// week
TimeUnit.Year.ToSymbol();
// y
```

## <a id="mix-this-into-your-framework-to-simplify-your-life">Mix this into your framework to simplify your life</a>
This is just a baseline and you can use this to simplify your day to day job. For example, in Asp.Net MVC we keep chucking `Display` attribute on ViewModel properties so `HtmlHelper` can generate correct labels for us; but, just like enums, in vast majority of cases we just need a space between the words in property name - so why not use `"string".Humanize` for that?!

Expand Down
2 changes: 2 additions & 0 deletions src/Humanizer.Tests.Shared/Humanizer.Tests.Shared.projitems
Expand Up @@ -82,6 +82,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Localisation\de\HeadingTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Localisation\de\OrdinalizeTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Localisation\de\TimeSpanHumanizeTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Localisation\de\TimeUnitToSymbolTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Localisation\el\DateHumanizeTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Localisation\el\TimeSpanHumanizeTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Localisation\en\DateToOrdinalWordsTests.cs" />
Expand Down Expand Up @@ -216,6 +217,7 @@
<Compile Include="$(MSBuildThisFileDirectory)StringExtensionsTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)StringHumanizeTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)TimeSpanHumanizeTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)TimeUnitToSymbolTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ToQuantityTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)TransformersTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)TruncatorTests.cs" />
Expand Down
@@ -0,0 +1,27 @@
using System;

using Humanizer.Localisation;

using Xunit;

namespace Humanizer.Tests.Localisation.de
{
[UseCulture("de-DE")]
public class TimeUnitToSymbolTests
{
[Theory]
[Trait("Translation", "Native speaker")]
[InlineData(TimeUnit.Millisecond, "ms")]
[InlineData(TimeUnit.Second, "s")]
[InlineData(TimeUnit.Minute, "min")]
[InlineData(TimeUnit.Hour, "h")]
[InlineData(TimeUnit.Day, "d")]
[InlineData(TimeUnit.Week, "Woche")]
[InlineData(TimeUnit.Month, "M")]
[InlineData(TimeUnit.Year, "a")]
public void ToSymbol(TimeUnit unit, string expected)
{
Assert.Equal(expected, unit.ToSymbol());
}
}
}
24 changes: 24 additions & 0 deletions src/Humanizer.Tests.Shared/TimeUnitToSymbolTests.cs
@@ -0,0 +1,24 @@
using Humanizer.Localisation;

using Xunit;

namespace Humanizer.Tests
{
[UseCulture("en-US")]
public class TimeUnitToSymbolTests
{
[Theory]
[InlineData(TimeUnit.Millisecond, "ms")]
[InlineData(TimeUnit.Second, "s")]
[InlineData(TimeUnit.Minute, "min")]
[InlineData(TimeUnit.Hour, "h")]
[InlineData(TimeUnit.Day, "d")]
[InlineData(TimeUnit.Week, "week")]
[InlineData(TimeUnit.Month, "mo")]
[InlineData(TimeUnit.Year, "y")]
public void ToSymbol(TimeUnit unit, string expected)
{
Assert.Equal(expected, unit.ToSymbol());
}
}
}
Expand Up @@ -1586,6 +1586,10 @@ namespace Humanizer
public static string Humanize(this System.TimeSpan timeSpan, int precision = 1, System.Globalization.CultureInfo culture = null, Humanizer.Localisation.TimeUnit maxUnit = 5, Humanizer.Localisation.TimeUnit minUnit = 0, string collectionSeparator = ", ", bool toWords = False) { }
public static string Humanize(this System.TimeSpan timeSpan, int precision, bool countEmptyUnits, System.Globalization.CultureInfo culture = null, Humanizer.Localisation.TimeUnit maxUnit = 5, Humanizer.Localisation.TimeUnit minUnit = 0, string collectionSeparator = ", ", bool toWords = False) { }
}
public class static TimeUnitToSymbolExtensions
{
public static string ToSymbol(this Humanizer.Localisation.TimeUnit unit, System.Globalization.CultureInfo culture = null) { }
}
public class static To
{
public static Humanizer.ICulturedStringTransformer LowerCase { get; }
Expand Down Expand Up @@ -1855,6 +1859,10 @@ namespace Humanizer.Localisation
{
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
{
Expand Down Expand Up @@ -1905,6 +1913,7 @@ namespace Humanizer.Localisation.Formatters
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
{
Expand All @@ -1914,6 +1923,7 @@ namespace Humanizer.Localisation.Formatters
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
Expand Down
7 changes: 7 additions & 0 deletions src/Humanizer/Localisation/Formatters/DefaultFormatter.cs
Expand Up @@ -83,6 +83,13 @@ public virtual string DataUnitHumanize(DataUnit dataUnit, double count, bool toS
return resourceValue;
}

/// <inheritdoc />
public virtual string TimeUnitHumanize(TimeUnit timeUnit)
{
var resourceKey = ResourceKeys.TimeUnitSymbol.GetResourceKey(timeUnit);
return Format(resourceKey);
}

private string GetResourceForDate(TimeUnit unit, Tense timeUnitTense, int count)
{
var resourceKey = ResourceKeys.DateHumanize.GetResourceKey(unit, timeUnitTense: timeUnitTense, count: count);
Expand Down
7 changes: 7 additions & 0 deletions src/Humanizer/Localisation/Formatters/IFormatter.cs
Expand Up @@ -51,5 +51,12 @@ public interface IFormatter
/// <param name="toSymbol">Indicates whether the data unit should be expressed as symbol or full word</param>
/// <returns>String representation of the provided DataUnit</returns>
string DataUnitHumanize(DataUnit dataUnit, double count, bool toSymbol = true);

/// <summary>
/// Returns the symbol for the given TimeUnit
/// </summary>
/// <param name="timeUnit">Time unit</param>
/// <returns>String representation of the provided TimeUnit</returns>
string TimeUnitHumanize(TimeUnit timeUnit);
}
}
28 changes: 28 additions & 0 deletions src/Humanizer/Localisation/ResourceKeys.TimeUnitSymbol.cs
@@ -0,0 +1,28 @@
namespace Humanizer.Localisation
{
public partial class ResourceKeys
{
/// <summary>
/// Encapsulates the logic required to get the resource keys for TimeUnit.ToSymbol
/// </summary>
public static class TimeUnitSymbol
{
/// <summary>
/// Examples: TimeUnit_Minute, TimeUnit_Hour.
/// </summary>
private const string TimeUnitFormat = "TimeUnit_{0}";

/// <summary>
/// Generates Resource Keys according to convention.
/// </summary>
/// <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>
/// <returns>Resource key, like TimeSpanHumanize_SingleMinute</returns>
public static string GetResourceKey(TimeUnit unit)
{
return TimeUnitFormat.FormatWith(unit);
}
}
}
}
24 changes: 24 additions & 0 deletions src/Humanizer/Properties/Resources.de.resx
Expand Up @@ -402,4 +402,28 @@
<data name="DataUnit_TerabyteSymbol" xml:space="preserve">
<value>TB</value>
</data>
<data name="TimeUnit_Millisecond" xml:space="preserve">
<value>ms</value>
</data>
<data name="TimeUnit_Second" xml:space="preserve">
<value>s</value>
</data>
<data name="TimeUnit_Minute" xml:space="preserve">
<value>min</value>
</data>
<data name="TimeUnit_Hour" xml:space="preserve">
<value>h</value>
</data>
<data name="TimeUnit_Day" xml:space="preserve">
<value>d</value>
</data>
<data name="TimeUnit_Week" xml:space="preserve">
<value>Woche</value>
</data>
<data name="TimeUnit_Month" xml:space="preserve">
<value>M</value>
</data>
<data name="TimeUnit_Year" xml:space="preserve">
<value>a</value>
</data>
</root>
24 changes: 24 additions & 0 deletions src/Humanizer/Properties/Resources.resx
Expand Up @@ -711,4 +711,28 @@
<data name="DataUnit_TerabyteSymbol" xml:space="preserve">
<value>TB</value>
</data>
<data name="TimeUnit_Millisecond" xml:space="preserve">
<value>ms</value>
</data>
<data name="TimeUnit_Second" xml:space="preserve">
<value>s</value>
</data>
<data name="TimeUnit_Minute" xml:space="preserve">
<value>min</value>
</data>
<data name="TimeUnit_Hour" xml:space="preserve">
<value>h</value>
</data>
<data name="TimeUnit_Day" xml:space="preserve">
<value>d</value>
</data>
<data name="TimeUnit_Week" xml:space="preserve">
<value>week</value>
</data>
<data name="TimeUnit_Month" xml:space="preserve">
<value>mo</value>
</data>
<data name="TimeUnit_Year" xml:space="preserve">
<value>y</value>
</data>
</root>
24 changes: 24 additions & 0 deletions src/Humanizer/TimeUnitToSymbolExtensions.cs
@@ -0,0 +1,24 @@
using System.Globalization;

using Humanizer.Localisation;
using Humanizer.Configuration;

namespace Humanizer
{
/// <summary>
/// Transform a time unit into a symbol; e.g. <see cref="TimeUnit.Year"/> => "a"
/// </summary>
public static class TimeUnitToSymbolExtensions
{
/// <summary>
/// TimeUnit.Day.ToSymbol() -> "d"
/// </summary>
/// <param name="unit">Unit of time to be turned to a symbol</param>
/// <param name="culture">Culture to use. If null, current thread's UI culture is used.</param>
/// <returns></returns>
public static string ToSymbol(this TimeUnit unit, CultureInfo culture = null)
{
return Configurator.GetFormatter(culture).TimeUnitHumanize(unit);
}
}
}

0 comments on commit bc1a9b7

Please sign in to comment.