diff --git a/readme.md b/readme.md
index 1537c359e..2abce6cc6 100644
--- a/readme.md
+++ b/readme.md
@@ -354,6 +354,14 @@ You can also pass a second argument, `ShowQuantityAs`, to `ToQuantity` to specif
"case".ToQuantity(5, ShowQuantityAs.None) => "cases"
```
+There is also an overload that allows you to format the number. You can pass in the format and the culture to be used.
+
+```C#
+"dollar".ToQuantity(2, "C0", new CultureInfo("en-US")) => "$2 dollars"
+"dollar".ToQuantity(2, "C2", new CultureInfo("en-US")) => "$2.00 dollars"
+"cases".ToQuantity(12000, "N0") => "12,000 cases"
+```
+
####Ordinalize
`Ordinalize` turns a number into an ordinal string used to denote the position in an ordered sequence such as 1st, 2nd, 3rd, 4th:
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 44996fe78..9bc08b7eb 100644
--- a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt
+++ b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.approve_public_api.approved.txt
@@ -338,6 +338,7 @@ public class To
public class ToQuantityExtensions
{
public string ToQuantity(string input, int quantity, Humanizer.ShowQuantityAs showQuantityAs) { }
+ public string ToQuantity(string input, int quantity, string format, System.IFormatProvider formatProvider) { }
}
public class Truncator
diff --git a/src/Humanizer.Tests/ToQuantityTests.cs b/src/Humanizer.Tests/ToQuantityTests.cs
index 9812b3d29..730222e3b 100644
--- a/src/Humanizer.Tests/ToQuantityTests.cs
+++ b/src/Humanizer.Tests/ToQuantityTests.cs
@@ -1,4 +1,6 @@
-using Xunit;
+using System;
+using System.Globalization;
+using Xunit;
using Xunit.Extensions;
namespace Humanizer.Tests
@@ -79,5 +81,38 @@ public void ToQuantityWords(string word, int quatity, string expected)
{
Assert.Equal(expected, word.ToQuantity(quatity, ShowQuantityAs.Words));
}
+
+ [Theory]
+ [InlineData("case", 0, null, "0 cases")]
+ [InlineData("case", 1, null, "1 case")]
+ [InlineData("case", 2, null, "2 cases")]
+ [InlineData("case", 1, "N0", "1 case")]
+ [InlineData("case", 2, "N0", "2 cases")]
+ [InlineData("case", 123456, "N0", "123,456 cases")]
+ [InlineData("case", 123456, "N2", "123,456.00 cases")]
+ [InlineData("dollar", 0, "C0", "$0 dollars")]
+ [InlineData("dollar", 1, "C0", "$1 dollar")]
+ [InlineData("dollar", 2, "C0", "$2 dollars")]
+ [InlineData("dollar", 2, "C2", "$2.00 dollars")]
+ public void ToQuantityWordsWithCurrentCultureFormatting(string word, int quantity, string format, string expected)
+ {
+ Assert.Equal(expected, word.ToQuantity(quantity, format));
+ }
+
+ [Theory]
+ [InlineData("case", 0, "N0", "it-IT", "0 cases")]
+ [InlineData("case", 1, "N0", "it-IT", "1 case")]
+ [InlineData("case", 2, "N0", "it-IT", "2 cases")]
+ [InlineData("case", 1234567, "N0", "it-IT", "1.234.567 cases")]
+ [InlineData("case", 1234567, "N2", "it-IT", "1.234.567,00 cases")]
+ [InlineData("euro", 0, "C0", "es-ES", "0 € euros")]
+ [InlineData("euro", 1, "C0", "es-ES", "1 € euro")]
+ [InlineData("euro", 2, "C0", "es-ES", "2 € euros")]
+ [InlineData("euro", 2, "C2", "es-ES", "2,00 € euros")]
+ public void ToQuantityWordsWithCustomCultureFormatting(string word, int quantity, string format, string cultureCode, string expected)
+ {
+ var culture = new CultureInfo(cultureCode);
+ Assert.Equal(expected, word.ToQuantity(quantity, format, culture), StringComparer.Create(culture, false));
+ }
}
}
diff --git a/src/Humanizer/ToQuantityExtensions.cs b/src/Humanizer/ToQuantityExtensions.cs
index 44e2ce164..d9986d8b3 100644
--- a/src/Humanizer/ToQuantityExtensions.cs
+++ b/src/Humanizer/ToQuantityExtensions.cs
@@ -1,4 +1,5 @@
-namespace Humanizer
+using System;
+namespace Humanizer
{
///
/// Enumerates the ways of displaying a quantity value when converting
@@ -44,6 +45,29 @@ public static class ToQuantityExtensions
///
///
public static string ToQuantity(this string input, int quantity, ShowQuantityAs showQuantityAs = ShowQuantityAs.Numeric)
+ {
+ return input.ToQuantity(quantity, showQuantityAs, format: null, formatProvider: null);
+ }
+
+ ///
+ /// Prefixes the provided word with the number and accordingly pluralizes or singularizes the word
+ ///
+ /// The word to be prefixes
+ /// The quantity of the word
+ /// A standard or custom numeric format string.
+ /// An object that supplies culture-specific formatting information.
+ ///
+ /// "request".ToQuantity(0) => "0 requests"
+ /// "request".ToQuantity(10000, format: "N0") => "10,000 requests"
+ /// "request".ToQuantity(1, format: "N0") => "1 request"
+ ///
+ ///
+ public static string ToQuantity(this string input, int quantity, string format, IFormatProvider formatProvider = null)
+ {
+ return input.ToQuantity(quantity, showQuantityAs: ShowQuantityAs.Numeric, format: format, formatProvider: formatProvider);
+ }
+
+ private static string ToQuantity(this string input, int quantity, ShowQuantityAs showQuantityAs = ShowQuantityAs.Numeric, string format = null, IFormatProvider formatProvider = null)
{
var transformedInput = quantity == 1
? input.Singularize(Plurality.CouldBeEither)
@@ -53,7 +77,7 @@ public static string ToQuantity(this string input, int quantity, ShowQuantityAs
return transformedInput;
if (showQuantityAs == ShowQuantityAs.Numeric)
- return string.Format("{0} {1}", quantity, transformedInput);
+ return string.Format(formatProvider, "{0} {1}", quantity.ToString(format, formatProvider), transformedInput);
return string.Format("{0} {1}", quantity.ToWords(), transformedInput);
}