Rehman.CurrencyTextify.Core
A lightweight, fully self-contained .NET library that converts money amounts ↔ spelled-out text for eight currency systems, including PKR, INR, USD, EUR, GBP, JPY, SAR, AED, KWD, and more.
Table of Contents
- Features
- Supported Currencies
- Installation
- Quick Start
- API Reference
- Configuration Options
- Sample Inputs and Outputs
- Advanced Usage
- Design Principles
- License
Features
| Feature |
Details |
| Flexible input |
Accepts decimal, double, int, long, or string ("23.90 INR", "$23.90", "INR23.90", "23,307") |
| Amount → Text |
Fully spelled-out English, correct grammar, optional "and", thousands grouping |
| Text → Amount |
Parses spelled-out text back to a numeric amount string |
| Fuzzy correction |
Automatically corrects common misspellings ("rupes" → "rupees", "fourtee" → "forty") |
| Negative amounts |
"Negative twenty dollars" ↔ "-20.00 USD" |
| Batch processing |
ToTextList / ToAmountList for lists of inputs |
| 8 currency systems |
Dollar, Euro, Pound, Yen, Rupee, Rial, Dirham, Dinar |
| Rounding modes |
Nearest (default), Up, Down, Truncate |
| Capitalisation styles |
SentenceCase, TitleCase, LowerCase, UpperCase |
| Subunit overrides |
Override "paise" with any custom term |
| Zero dependencies |
No third-party packages required |
| Extensible |
Add currencies or custom converters without changing existing code |
Supported Currencies
| System |
ISO Codes |
Major Unit |
Subunit |
| Dollar |
USD |
dollar |
cent |
| Euro |
EUR |
euro |
cent |
| Pound Sterling |
GBP |
pound |
penny / pence |
| Yen |
JPY |
yen |
(none) |
| Rupee |
INR, PKR, LKR, NPR, MUR |
rupee |
paisa / paise |
| Rial |
SAR, OMR, QAR, IRR |
rial |
halala |
| Dirham |
AED, MAD |
dirham |
fils |
| Dinar |
KWD, BHD, JOD, IQD, LYD, TND |
dinar |
fil / fils |
Installation
.NET CLI
dotnet add package Rehman.CurrencyTextify.Core
Package Manager Console (Visual Studio)
Install-Package Rehman.CurrencyTextify.Core
Manual (csproj)
<PackageReference Include="Rehman.CurrencyTextify.Core" Version="1.0.0" />
Quick Start
using Rehman.CurrencyTextify.Core;
// Amount string → Text
string text = CurrencyTextify.ToText("23.90 INR");
// → "Twenty-three rupees and ninety paise"
// Typed amount → Text
string dollars = CurrencyTextify.ToText(23307, "USD");
// → "Twenty-three thousand three hundred and seven dollars"
// Text → Amount
string amount = CurrencyTextify.ToAmount("Twenty-three rupees and ninety paise");
// → "23.90 INR"
// Fuzzy correction
string corrected = CurrencyTextify.ToAmount("twenty three rupes ninety paisa");
// → "23.90 INR"
API Reference
ToText — Amount to Text
All overloads return a string containing the fully spelled-out currency text.
No exception is thrown; malformed input returns "zero".
// --- String input (most flexible) ---
string CurrencyTextify.ToText(string input, ConversionOptions options = null)
// Accepts: "23.90 INR", "INR 23.90", "23.90INR", "$23.90", "23,307 USD",
// "1500 PKR", "-50 EUR", "¥1000"
// --- Typed numeric input ---
string CurrencyTextify.ToText(decimal amount, string currencyCode, ConversionOptions options = null)
string CurrencyTextify.ToText(double amount, string currencyCode, ConversionOptions options = null)
string CurrencyTextify.ToText(int amount, string currencyCode, ConversionOptions options = null)
string CurrencyTextify.ToText(long amount, string currencyCode, ConversionOptions options = null)
Examples
CurrencyTextify.ToText("23.90 INR")
// → "Twenty-three rupees and ninety paise"
CurrencyTextify.ToText("1500 PKR")
// → "One thousand five hundred rupees"
CurrencyTextify.ToText(23307, "USD")
// → "Twenty-three thousand three hundred and seven dollars"
CurrencyTextify.ToText(0.50m, "GBP")
// → "Fifty pence"
CurrencyTextify.ToText(1000000m, "EUR")
// → "One million euros"
CurrencyTextify.ToText(-250.75m, "SAR")
// → "Negative two hundred and fifty rials and seventy-five halalas"
CurrencyTextify.ToText(1500.500m, "KWD")
// → "One thousand five hundred dinars and five hundred fils"
CurrencyTextify.ToText(1000, "JPY")
// → "One thousand yen"
CurrencyTextify.ToText(0m, "USD")
// → "Zero dollars"
ToAmount — Text to Amount
string CurrencyTextify.ToAmount(string text, ConversionOptions options = null)
Returns an amount string in the format "<value> <CODE>", e.g., "23.90 INR".
CurrencyTextify.ToAmount("Twenty-three rupees and ninety paise")
// → "23.90 INR"
CurrencyTextify.ToAmount("twenty three rupes ninety paisa")
// → "23.90 INR" (fuzzy correction applied)
CurrencyTextify.ToAmount("One thousand five hundred rupees")
// → "1500.00 INR"
CurrencyTextify.ToAmount("Twenty-three thousand three hundred and seven dollars")
// → "23307.00 USD"
CurrencyTextify.ToAmount("Negative fifty euros and twenty-five cents")
// → "-50.25 EUR"
CurrencyTextify.ToAmount("One thousand five hundred dinars and five hundred fils")
// → "1500.500 KWD"
As a decimal value
decimal value = CurrencyTextify.ToDecimal("Twenty-three rupees and ninety paise");
// → 23.90
Batch Processing
List<string> CurrencyTextify.ToTextList(IEnumerable<string> inputs, ConversionOptions options = null)
List<string> CurrencyTextify.ToAmountList(IEnumerable<string> texts, ConversionOptions options = null)
Examples
var inputs = new List<string> { "23.90 INR", "23307 USD", "1500 PKR", "100 EUR" };
List<string> results = CurrencyTextify.ToTextList(inputs);
// →
// "Twenty-three rupees and ninety paise"
// "Twenty-three thousand three hundred and seven dollars"
// "One thousand five hundred rupees"
// "One hundred euros"
var texts = new List<string>
{
"Twenty-three rupees and ninety paise",
"Twenty-three thousand three hundred and seven dollars",
"One thousand five hundred rupees"
};
List<string> amounts = CurrencyTextify.ToAmountList(texts);
// → [ "23.90 INR", "23307.00 USD", "1500.00 INR" ]
Configuration Options
Pass a ConversionOptions object to any method to customise behaviour.
var options = new ConversionOptions
{
DefaultCurrency = "PKR", // fallback when no currency detected
Rounding = RoundingMode.Nearest, // Nearest | Up | Down | Truncate
IncludeAnd = true, // "dollars and fifty cents"
Capitalisation = CapitalisationStyle.SentenceCase, // SentenceCase | TitleCase | LowerCase | UpperCase
SubunitNameOverride = null, // e.g., "pence" to override default
UseFuzzyMatching = true, // auto-correct spelling in ToAmount
EnableDiagnostics = false, // write trace to Debug output
};
Rounding Modes
| Value |
Behaviour |
Nearest |
Standard round-half-up (default) |
Up |
Always round up (ceiling) |
Down |
Always round down (floor) |
Truncate |
Drop the extra digits without rounding |
Capitalisation Styles
| Value |
Example |
SentenceCase |
"Twenty-three rupees and ninety paise" |
TitleCase |
"Twenty-Three Rupees And Ninety Paise" |
LowerCase |
"twenty-three rupees and ninety paise" |
UpperCase |
"TWENTY-THREE RUPEES AND NINETY PAISE" |
Subunit Name Override
var options = new ConversionOptions { SubunitNameOverride = "paisas" };
CurrencyTextify.ToText("23.90 INR", options);
// → "Twenty-three rupees and ninety paisas"
Disable "And"
var options = new ConversionOptions { IncludeAnd = false };
CurrencyTextify.ToText("23307.50 USD", options);
// → "Twenty-three thousand three hundred seven dollars fifty cents"
Dollar (USD)
| Input |
Output |
"23307 USD" |
"Twenty-three thousand three hundred and seven dollars" |
"$23.90" |
"Twenty-three dollars and ninety cents" |
"-50.25 USD" |
"Negative fifty dollars and twenty-five cents" |
"1000000 USD" |
"One million dollars" |
"0 USD" |
"Zero dollars" |
Euro (EUR)
| Input |
Output |
"100.01 EUR" |
"One hundred euros and one cent" |
"€1500" |
"One thousand five hundred euros" |
"999999.99 EUR" |
"Nine hundred ninety-nine thousand nine hundred and ninety-nine euros and ninety-nine cents" |
Pound Sterling (GBP)
| Input |
Output |
"1.01 GBP" |
"One pound and one penny" |
"£50.20" |
"Fifty pounds and twenty pence" |
Yen (JPY)
| Input |
Output |
"1000 JPY" |
"One thousand yen" |
"¥50000" |
"Fifty thousand yen" |
Rupee (INR / PKR)
| Input |
Output |
"23.90 INR" |
"Twenty-three rupees and ninety paise" |
"1500 PKR" |
"One thousand five hundred rupees" |
"100000.50 INR" |
"One hundred thousand rupees and fifty paise" |
"Rs. 5000" |
"Five thousand rupees" |
Rial (SAR)
| Input |
Output |
"500 SAR" |
"Five hundred rials" |
"1200.75 SAR" |
"One thousand two hundred rials and seventy-five halalas" |
Dirham (AED)
| Input |
Output |
"250 AED" |
"Two hundred and fifty dirhams" |
"1000.50 AED" |
"One thousand dirhams and fifty fils" |
Dinar (KWD — 3 decimal places)
| Input |
Output |
"1500.500 KWD" |
"One thousand five hundred dinars and five hundred fils" |
"10.001 BHD" |
"Ten dinars and one fil" |
Advanced Usage
Custom Engine (Dependency Injection)
// Use your own implementations of any interface
var engine = new CurrencyTextifyEngine(
amountParser: new MyCustomAmountParser(),
textConverter: new TextConverter(), // built-in
textParser: new TextParser() // built-in
);
string result = engine.ToText("23.90 INR");
Registering a New Currency
Implement ICurrencyRule and register it once at application start-up.
No existing code needs to be changed.
public sealed class FrancoRule : ICurrencyRule
{
public string PrimaryCode => "CHF";
public IReadOnlyList<string> AllCodes => new[] { "CHF" };
public string MajorSingular => "franc";
public string MajorPlural => "francs";
public string MinorSingular => "centime";
public string MinorPlural => "centimes";
public int DecimalPlaces => 2;
public IReadOnlyList<string> Symbols => new[] { "Fr", "CHF" };
}
// Register once (e.g., in Program.cs / Startup.cs)
CurrencyRegistry.Register(new FrancoRule());
// Use immediately
string text = CurrencyTextify.ToText("100.50 CHF");
// → "One hundred francs and fifty centimes"
Diagnostics / Logging
var options = new ConversionOptions { EnableDiagnostics = true };
string result = CurrencyTextify.ToText("23.90 INR", options);
// Trace output written to System.Diagnostics.Debug:
// [AmountParser] Parsing: '23.90 INR'
// [CurrencyTextifyEngine] ...
Redirect Debug output to your preferred logger:
// In a test project or console app
Trace.Listeners.Add(new ConsoleTraceListener());
Design Principles
| Principle |
Implementation |
| Open/Closed |
Add currencies via CurrencyRegistry.Register; no existing code is modified |
| Interface segregation |
IAmountParser, ITextConverter, ITextParser are small, focused contracts |
| Dependency injection |
CurrencyTextifyEngine accepts all components via constructor |
| Fail-safe |
Every public method catches exceptions and returns "zero" / "0.00 USD" |
| Zero dependencies |
The package references only the BCL; no NuGet dependencies |
| Multi-target |
Targets netstandard2.0, net6.0, and net8.0 |
License
This project is licensed under the MIT License.
Rehman.CurrencyTextify.Core — making money talk.