From 689802b55f94ccb8e4e8d33b121f36b85d9e7108 Mon Sep 17 00:00:00 2001 From: hangy Date: Sat, 3 Jul 2021 13:52:04 +0200 Subject: [PATCH 1/4] Add TimeUnitToSymbolTests that should be fulfilled --- .../Humanizer.Tests.Shared.projitems | 2 ++ .../Localisation/de/TimeUnitToSymbolTests.cs | 27 +++++++++++++++++++ .../TimeUnitToSymbolTests.cs | 24 +++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 src/Humanizer.Tests.Shared/Localisation/de/TimeUnitToSymbolTests.cs create mode 100644 src/Humanizer.Tests.Shared/TimeUnitToSymbolTests.cs diff --git a/src/Humanizer.Tests.Shared/Humanizer.Tests.Shared.projitems b/src/Humanizer.Tests.Shared/Humanizer.Tests.Shared.projitems index 17c44126e..590113f49 100644 --- a/src/Humanizer.Tests.Shared/Humanizer.Tests.Shared.projitems +++ b/src/Humanizer.Tests.Shared/Humanizer.Tests.Shared.projitems @@ -71,6 +71,7 @@ + @@ -203,6 +204,7 @@ + diff --git a/src/Humanizer.Tests.Shared/Localisation/de/TimeUnitToSymbolTests.cs b/src/Humanizer.Tests.Shared/Localisation/de/TimeUnitToSymbolTests.cs new file mode 100644 index 000000000..2b334ba26 --- /dev/null +++ b/src/Humanizer.Tests.Shared/Localisation/de/TimeUnitToSymbolTests.cs @@ -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()); + } + } +} diff --git a/src/Humanizer.Tests.Shared/TimeUnitToSymbolTests.cs b/src/Humanizer.Tests.Shared/TimeUnitToSymbolTests.cs new file mode 100644 index 000000000..ec5c07b1b --- /dev/null +++ b/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, "a")] + public void ToSymbol(TimeUnit unit, string expected) + { + Assert.Equal(expected, unit.ToSymbol()); + } + } +} From 6b3eb5311e2252a63d4923bddd7a381494f7921c Mon Sep 17 00:00:00 2001 From: hangy Date: Sat, 3 Jul 2021 16:10:48 +0200 Subject: [PATCH 2/4] Implement TimeUnitToSymbolExtensions.ToSymbol method --- ...provalTest.approve_public_api.approved.txt | 10 +++++++ .../Formatters/DefaultFormatter.cs | 7 +++++ .../Localisation/Formatters/IFormatter.cs | 7 +++++ .../ResourceKeys.TimeUnitSymbol.cs | 28 +++++++++++++++++++ src/Humanizer/Properties/Resources.de.resx | 24 ++++++++++++++++ src/Humanizer/Properties/Resources.resx | 24 ++++++++++++++++ src/Humanizer/TimeUnitToSymbolExtensions.cs | 24 ++++++++++++++++ 7 files changed, 124 insertions(+) create mode 100644 src/Humanizer/Localisation/ResourceKeys.TimeUnitSymbol.cs create mode 100644 src/Humanizer/TimeUnitToSymbolExtensions.cs diff --git a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt index 53cfd1a1c..f41cef7d1 100644 --- a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt +++ b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt @@ -1583,6 +1583,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; } @@ -1852,6 +1856,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 { @@ -1902,6 +1910,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 { @@ -1911,6 +1920,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 diff --git a/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs b/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs index d3b410990..baa74d7e6 100644 --- a/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs +++ b/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs @@ -83,6 +83,13 @@ public virtual string DataUnitHumanize(DataUnit dataUnit, double count, bool toS return resourceValue; } + /// + 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); diff --git a/src/Humanizer/Localisation/Formatters/IFormatter.cs b/src/Humanizer/Localisation/Formatters/IFormatter.cs index 64e06c3dd..772d66c24 100644 --- a/src/Humanizer/Localisation/Formatters/IFormatter.cs +++ b/src/Humanizer/Localisation/Formatters/IFormatter.cs @@ -51,5 +51,12 @@ public interface IFormatter /// Indicates whether the data unit should be expressed as symbol or full word /// String representation of the provided DataUnit string DataUnitHumanize(DataUnit dataUnit, double count, bool toSymbol = true); + + /// + /// Returns the symbol for the given TimeUnit + /// + /// Time unit + /// String representation of the provided TimeUnit + string TimeUnitHumanize(TimeUnit timeUnit); } } diff --git a/src/Humanizer/Localisation/ResourceKeys.TimeUnitSymbol.cs b/src/Humanizer/Localisation/ResourceKeys.TimeUnitSymbol.cs new file mode 100644 index 000000000..c008fdb47 --- /dev/null +++ b/src/Humanizer/Localisation/ResourceKeys.TimeUnitSymbol.cs @@ -0,0 +1,28 @@ +namespace Humanizer.Localisation +{ + public partial class ResourceKeys + { + /// + /// Encapsulates the logic required to get the resource keys for TimeUnit.ToSymbol + /// + public static class TimeUnitSymbol + { + /// + /// Examples: TimeUnit_Minute, TimeUnit_Hour. + /// + private const string TimeUnitFormat = "TimeUnit_{0}"; + + /// + /// Generates Resource Keys according to convention. + /// + /// Time unit, . + /// Number of units, default is One. + /// Result to words, default is false. + /// Resource key, like TimeSpanHumanize_SingleMinute + public static string GetResourceKey(TimeUnit unit) + { + return TimeUnitFormat.FormatWith(unit); + } + } + } +} diff --git a/src/Humanizer/Properties/Resources.de.resx b/src/Humanizer/Properties/Resources.de.resx index 37f688366..b127c0b49 100644 --- a/src/Humanizer/Properties/Resources.de.resx +++ b/src/Humanizer/Properties/Resources.de.resx @@ -402,4 +402,28 @@ TB + + ms + + + s + + + min + + + h + + + d + + + Woche + + + M + + + a + \ No newline at end of file diff --git a/src/Humanizer/Properties/Resources.resx b/src/Humanizer/Properties/Resources.resx index 8683674b6..45672c3a7 100644 --- a/src/Humanizer/Properties/Resources.resx +++ b/src/Humanizer/Properties/Resources.resx @@ -711,4 +711,28 @@ TB + + ms + + + s + + + min + + + h + + + d + + + week + + + mo + + + a + \ No newline at end of file diff --git a/src/Humanizer/TimeUnitToSymbolExtensions.cs b/src/Humanizer/TimeUnitToSymbolExtensions.cs new file mode 100644 index 000000000..86a3b6bd6 --- /dev/null +++ b/src/Humanizer/TimeUnitToSymbolExtensions.cs @@ -0,0 +1,24 @@ +using System.Globalization; + +using Humanizer.Localisation; +using Humanizer.Configuration; + +namespace Humanizer +{ + /// + /// Transform a time unit into a symbol; e.g. => "a" + /// + public static class TimeUnitToSymbolExtensions + { + /// + /// TimeUnit.Day.ToSymbol() -> "d" + /// + /// Unit of time to be turned to a symbol + /// Culture to use. If null, current thread's UI culture is used. + /// + public static string ToSymbol(this TimeUnit unit, CultureInfo culture = null) + { + return Configurator.GetFormatter(culture).TimeUnitHumanize(unit); + } + } +} From 630b78c50e2399d494476283310d67041e054d88 Mon Sep 17 00:00:00 2001 From: hangy Date: Sat, 3 Jul 2021 16:18:18 +0200 Subject: [PATCH 3/4] Add example for TimeUnitToSymbolExtensions.ToSymbol --- readme.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/readme.md b/readme.md index a944800f9..d02671013 100644 --- a/readme.md +++ b/readme.md @@ -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) @@ -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". +### Time unit to symbol +Humanizer can translate time units to their symbols: + +```C# +TimeUnit.Day.ToSymbol(); +// d +TimeUnit.Week.ToSymbol(); +// week +TimeUnit.Year.ToSymbol(); +// a +``` + ## Mix this into your framework to simplify your life 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?! From 18138ed79657ef95b6d65e9b8b5ba9d91fe76141 Mon Sep 17 00:00:00 2001 From: hangy Date: Wed, 27 Oct 2021 20:35:36 +0200 Subject: [PATCH 4/4] Use 'y' instead of 'a' for `TimeUnit.Year` --- readme.md | 2 +- src/Humanizer.Tests.Shared/TimeUnitToSymbolTests.cs | 2 +- src/Humanizer/Properties/Resources.resx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index d02671013..79ab0e674 100644 --- a/readme.md +++ b/readme.md @@ -1119,7 +1119,7 @@ TimeUnit.Day.ToSymbol(); TimeUnit.Week.ToSymbol(); // week TimeUnit.Year.ToSymbol(); -// a +// y ``` ## Mix this into your framework to simplify your life diff --git a/src/Humanizer.Tests.Shared/TimeUnitToSymbolTests.cs b/src/Humanizer.Tests.Shared/TimeUnitToSymbolTests.cs index ec5c07b1b..759b17e1e 100644 --- a/src/Humanizer.Tests.Shared/TimeUnitToSymbolTests.cs +++ b/src/Humanizer.Tests.Shared/TimeUnitToSymbolTests.cs @@ -15,7 +15,7 @@ public class TimeUnitToSymbolTests [InlineData(TimeUnit.Day, "d")] [InlineData(TimeUnit.Week, "week")] [InlineData(TimeUnit.Month, "mo")] - [InlineData(TimeUnit.Year, "a")] + [InlineData(TimeUnit.Year, "y")] public void ToSymbol(TimeUnit unit, string expected) { Assert.Equal(expected, unit.ToSymbol()); diff --git a/src/Humanizer/Properties/Resources.resx b/src/Humanizer/Properties/Resources.resx index 45672c3a7..d1c7050c4 100644 --- a/src/Humanizer/Properties/Resources.resx +++ b/src/Humanizer/Properties/Resources.resx @@ -733,6 +733,6 @@ mo - a + y \ No newline at end of file