Write numbers and ordinals in words
Orientation
Use ToWords for cardinal words, ToOrdinalWords for word ordinals, and Ordinalize when the number should remain numeric with a localized ordinal form. Select culture explicitly and add grammatical gender or word form only when the selected locale advertises that capability.
Example
The shared number example verifies cardinal words, ordinal words, a numeric ordinal, a Roman numeral, a byte size, and a quantity:
using System.Globalization;
using Humanizer;
var culture = CultureInfo.GetCultureInfo("en-US");
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
AssertEqual("forty-two", 42.ToWords(culture));
AssertEqual("twenty-first", 21.ToOrdinalWords(culture));
AssertEqual("21st", 21.Ordinalize(culture));
AssertEqual("XIV", 14.ToRoman());
AssertEqual("1.5 KB", 1536.Bytes().Humanize("0.0", culture));
AssertEqual("two people", "person".ToQuantity(2, ShowQuantityAs.Words));
Console.WriteLine("forty-two; twenty-first; XIV; 1.5 KB; two people");
static void AssertEqual<T>(T expected, T actual)
{
if (!EqualityComparer<T>.Default.Equals(actual, expected))
throw new InvalidOperationException($"Expected '{expected}', got '{actual}'.");
}
Choose the output
| Desired output | API |
|---|---|
forty-two | 42.ToWords(culture) |
twenty-first | 21.ToOrdinalWords(culture) |
21st | 21.Ordinalize(culture) |
| A locale-specific tuple word | number.ToTuple(culture) |
ToWords supports int and long cardinal values. Word ordinals are int-based. Some overloads accept GrammaticalGender, WordForm, or addAnd; use named arguments so intent remains clear across overload changes.
Pitfall
Grammar features differ by locale. Do not infer gender, abbreviation, Eifeler, or ordinal-word support from cardinal support. String Ordinalize parses the input using culture and can throw for malformed or out-of-range text; prefer the numeric overload when the application already has a number.
Version notes
The basic number-word and ordinal APIs span the documented corpus, but overloads and locale grammar have changed. The verified source runs against the selected package. Historical snapshots link to their own capability data and signatures.