diff --git a/src/Humanizer.Tests.Shared/HeadingTests.cs b/src/Humanizer.Tests.Shared/HeadingTests.cs
index e4b312ce2..55d3775c2 100644
--- a/src/Humanizer.Tests.Shared/HeadingTests.cs
+++ b/src/Humanizer.Tests.Shared/HeadingTests.cs
@@ -1,4 +1,6 @@
-using Xunit;
+using System.Globalization;
+
+using Xunit;
namespace Humanizer.Tests
{
@@ -154,9 +156,49 @@ public void FromShortHeading(string heading, double expected)
[InlineData(348.7, '↑')]
[InlineData(348.8, '↑')]
[Theory]
- public void ToHeadignArrow(double heading, char expected)
+ public void ToHeadingArrow(double heading, char expected)
{
Assert.Equal(expected, heading.ToHeadingArrow());
}
+
+ [InlineData('↑', 0)]
+ [InlineData('↗', 45)]
+ [InlineData('→', 90)]
+ [InlineData('↘', 135)]
+ [InlineData('↓', 180)]
+ [InlineData('↙', 225)]
+ [InlineData('←', 270)]
+ [InlineData('↖', 315)]
+ [InlineData('\n', -1)]
+ [Theory]
+ public void FromHeadingArrow(char heading, double expected)
+ {
+ Assert.Equal(expected, heading.FromHeadingArrow());
+ }
+
+ [InlineData("↑", 0)]
+ [InlineData("↗", 45)]
+ [InlineData("→", 90)]
+ [InlineData("↘", 135)]
+ [InlineData("↓", 180)]
+ [InlineData("↙", 225)]
+ [InlineData("←", 270)]
+ [InlineData("↖", 315)]
+ [InlineData("", -1)]
+ [InlineData("xyz", -1)]
+ [Theory]
+ public void FromHeadingArrow_Also_Works_With_Strings(string heading, double expected)
+ {
+ Assert.Equal(expected, heading.FromHeadingArrow());
+ }
+
+ [InlineData("NNW", "en-US", 337.5)]
+ [InlineData("ØNØ", "da", 67.5)]
+ [InlineData("O", "de-DE", 90.0)]
+ [Theory]
+ public void FromShortHeading_CanSpecifyCultureExplicitly(string heading, string culture, double expected)
+ {
+ Assert.Equal(expected, heading.FromAbbreviatedHeading(new CultureInfo(culture)));
+ }
}
}
diff --git a/src/Humanizer.Tests.Shared/Localisation/de/HeadingTests.cs b/src/Humanizer.Tests.Shared/Localisation/de/HeadingTests.cs
index c0229d14f..3f06be796 100644
--- a/src/Humanizer.Tests.Shared/Localisation/de/HeadingTests.cs
+++ b/src/Humanizer.Tests.Shared/Localisation/de/HeadingTests.cs
@@ -82,5 +82,27 @@ public void ToHeading(double heading, string expected)
{
Assert.Equal(expected, heading.ToHeading(HeadingStyle.Full));
}
+
+ [InlineData("N", 0)]
+ [InlineData("NNO", 22.5)]
+ [InlineData("NO", 45)]
+ [InlineData("ONO", 67.5)]
+ [InlineData("O", 90)]
+ [InlineData("OSO", 112.5)]
+ [InlineData("SO", 135)]
+ [InlineData("SSO", 157.5)]
+ [InlineData("S", 180)]
+ [InlineData("SSW", 202.5)]
+ [InlineData("SW", 225)]
+ [InlineData("WSW", 247.5)]
+ [InlineData("W", 270)]
+ [InlineData("WNW", 292.5)]
+ [InlineData("NW", 315)]
+ [InlineData("NNW", 337.5)]
+ [Theory]
+ public void FromShortHeading(string heading, double expected)
+ {
+ Assert.Equal(expected, heading.FromAbbreviatedHeading());
+ }
}
}
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..7b7e1d0a8 100644
--- a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt
+++ b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt
@@ -127,6 +127,9 @@ namespace Humanizer
public class static HeadingExtensions
{
public static double FromAbbreviatedHeading(this string heading) { }
+ public static double FromAbbreviatedHeading(this string heading, System.Globalization.CultureInfo culture = null) { }
+ public static double FromHeadingArrow(this char heading) { }
+ public static double FromHeadingArrow(this string heading) { }
public static string ToHeading(this double heading, Humanizer.HeadingStyle style = 0, System.Globalization.CultureInfo culture = null) { }
public static char ToHeadingArrow(this double heading) { }
}
diff --git a/src/Humanizer/HeadingExtensions.cs b/src/Humanizer/HeadingExtensions.cs
index a897427e7..5a1621b32 100644
--- a/src/Humanizer/HeadingExtensions.cs
+++ b/src/Humanizer/HeadingExtensions.cs
@@ -1,5 +1,6 @@
using System;
using System.Globalization;
+
using Humanizer.Localisation;
namespace Humanizer
@@ -73,14 +74,67 @@ public static char ToHeadingArrow(this double heading)
/// The heading. -1 if the heading could not be parsed.
public static double FromAbbreviatedHeading(this string heading)
{
- var index = Array.IndexOf(headings, heading.ToUpperInvariant());
+ return heading.FromAbbreviatedHeading(null);
+ }
+
+ ///
+ /// Returns a heading based on the short textual representation of the heading.
+ ///
+ /// The culture of the heading
+ /// The heading. -1 if the heading could not be parsed.
+ public static double FromAbbreviatedHeading(this string heading, CultureInfo culture = null)
+ {
+ if (heading == null)
+ {
+ throw new ArgumentNullException(nameof(heading));
+ }
+
+ culture ??= CultureInfo.CurrentCulture;
+
+ var upperCaseHeading = culture.TextInfo.ToUpper(heading);
+ for (var index = 0; index < headings.Length; ++index)
+ {
+ var localizedShortHeading = Resources.GetResource($"{headings[index]}_Short", culture);
+ if (culture.CompareInfo.Compare(upperCaseHeading, localizedShortHeading) == 0)
+ {
+ return (index * 22.5);
+ }
+ }
+
+ return -1;
+ }
+ ///
+ /// Returns a heading based on the heading arrow.
+ ///
+ public static double FromHeadingArrow(this char heading)
+ {
+ var index = Array.IndexOf(headingArrows, heading);
+
if (index == -1)
{
return -1;
}
- return (index * 22.5);
+ return (index * 45.0);
+ }
+
+ ///
+ /// Returns a heading based on the heading arrow.
+ ///
+ public static double FromHeadingArrow(this string heading)
+ {
+ if (heading == null)
+ {
+ throw new ArgumentNullException(nameof(heading));
+ }
+
+ if (heading.Length != 1)
+ {
+ return -1;
+ }
+
+ return heading[0].FromHeadingArrow();
}
}
}