NumWordify 2.4.0
dotnet add package NumWordify --version 2.4.0
NuGet\Install-Package NumWordify -Version 2.4.0
<PackageReference Include="NumWordify" Version="2.4.0" />
<PackageVersion Include="NumWordify" Version="2.4.0" />
<PackageReference Include="NumWordify" />
paket add NumWordify --version 2.4.0
#r "nuget: NumWordify, 2.4.0"
#:package NumWordify@2.4.0
#addin nuget:?package=NumWordify&version=2.4.0
#tool nuget:?package=NumWordify&version=2.4.0
NumWordify
NumWordify converts decimal numbers into words, with multi-language and multi-currency support.
Every example on this page is asserted by a test in tests/NumWordify.Tests, including the JSON schema block, which is parsed straight out of this file. The outputs shown here are the outputs you get.
Contents
- Features
- Installation
- Usage
- Precision and rounding
- Range
- Error handling
- Supported cultures
- Known limitations
- Custom localization
- Adding a new language
- Schema reference
- Migrating from 1.x
- Project structure
Features
- Numbers to words, with or without currency
- Seven languages: English, Turkish, French, Spanish, Portuguese, Russian, German
- Per-locale currency maps (
"EUR","USD", …) plus arbitrary custom currencies - Irregular number handling: teens, vigesimal forms (French 70–99), fused forms (Spanish 21–29), apocope (
UN MILLÓN,UN EURO), plural scale words (DEUX MILLIONS), and the adjective/noun split that decides FrenchDEUX CENT MILLEversusDEUX CENTS MILLIONS - Currency names that agree in number (
ONE DOLLAR/TWO DOLLARS) - Configurable fractional precision (0–6 digits) with away-from-zero rounding
- Negative numbers and zero
- Immutable, thread-safe converters; localization files are parsed once and cached
- Fully extensible through JSON files or a localization model you build in code
Installation
dotnet add package NumWordify
Targets net9.0, net8.0, net7.0, net6.0 and netstandard2.0.
Usage
Basic usage
using NumWordify.Extensions;
using NumWordify.Models;
using System.Globalization;
decimal amount = 1234.56M;
amount.ToWords("tr-TR");
// "BİN İKİ YÜZ OTUZ DÖRT TL ELLİ ALTI Kr"
amount.ToWords(new CultureInfo("tr-TR"));
// "BİN İKİ YÜZ OTUZ DÖRT TL ELLİ ALTI Kr"
amount.ToWordsWithoutCurrency("tr-TR");
// "BİN İKİ YÜZ OTUZ DÖRT NOKTA ELLİ ALTI"
11234.56M.ToWords("en-US");
// "ELEVEN THOUSAND TWO HUNDRED THIRTY-FOUR DOLLARS FIFTY-SIX CENTS"
1234.56M.ToWords("fr-FR");
// "MILLE DEUX CENT TRENTE-QUATRE EUROS CINQUANTE-SIX CENTIMES"
1234.56M.ToWords("es-ES");
// "MIL DOSCIENTOS TREINTA Y CUATRO EUROS CINCUENTA Y SEIS CÉNTIMOS"
Culture matching is case-insensitive and falls back within a language, so "EN-US", "en" and "en-GB" all resolve to en-US.
Currency
Pick one of the currencies the locale already names:
1234.56M.ToWords("tr-TR", "EUR");
// "BİN İKİ YÜZ OTUZ DÖRT EURO ELLİ ALTI SENT"
Or supply your own:
var currency = new CurrencyModel { Major = "EURO", Minor = "SENT" };
1234.56M.ToWords("tr-TR", currency);
// "BİN İKİ YÜZ OTUZ DÖRT EURO ELLİ ALTI SENT"
Set MajorSingular / MinorSingular when the language inflects the currency name:
1.01M.ToWords("en-US");
// "ONE DOLLAR ONE CENT"
2.02M.ToWords("en-US");
// "TWO DOLLARS TWO CENTS"
Cultures without their own localization
A culture that resolves through language fallback gets the right number words, but its currency is a different question — es-MX borrows Spanish number words, and the Spanish locale's default currency is the euro. Assuming it would be wrong in a way nobody notices, so it is refused:
1M.ToWordsWithoutCurrency("es-MX"); // "UNO COMA CERO"
1M.ToWords("es-MX", "MXN"); // "UN PESO CERO CENTAVOS"
1M.ToWords("es-MX"); // throws AmbiguousCurrencyException
A culture that names no region at all ("es") is not contradicting the locale, so it takes the default currency.
Checking a culture before using it
CultureInfo.CurrentCulture is whatever the machine is set to, and only seven languages ship with the library. Resolving and naming a currency are two separate questions, so the guard answers both — en-GB resolves to the English number words, but their default currency is the US dollar, and the library will not print DOLLARS for a British amount:
var machine = CultureInfo.CurrentCulture;
var culture = NumberToWordsConverter.IsCultureSupported(machine, out var currencyApplies) && currencyApplies
? machine.Name
: "en-US";
amount.ToWords(culture);
NumberToWordsConverter.SupportedCultures;
// ["de-DE", "en-US", "es-ES", "fr-FR", "pt-PT", "ru-RU", "tr-TR"]
The single-argument IsCultureSupported(culture) answers only "do the number words resolve?", which is the right question for ToWordsWithoutCurrency and for supplying your own currency:
1M.ToWordsWithoutCurrency("en-GB"); // "ONE POINT ZERO"
1M.ToWords("en-GB", "GBP"); // "ONE POUND ZERO PENCE"
1M.ToWords("en-GB"); // throws AmbiguousCurrencyException
Negative numbers and zero
(-1234.56M).ToWords("tr-TR");
// "EKSİ BİN İKİ YÜZ OTUZ DÖRT TL ELLİ ALTI Kr"
0M.ToWords("tr-TR");
// "SIFIR TL SIFIR Kr"
(-0.001M).ToWords("en-US");
// "ZERO DOLLARS ZERO CENTS" — a value that rounds to zero is not reported as negative
Options
The overloads cover the common combinations; WordifyOptions covers the rest and is the better fit when the settings come from configuration.
var options = new WordifyOptions { Culture = "tr-TR", CurrencyCode = "USD" };
1M.ToWords(options); // "BİR DOLAR SIFIR SENT"
1M.ToWordsWithoutCurrency(options); // "BİR NOKTA SIFIR"
Reusing a converter
NumberToWordsConverter is immutable and safe to share across threads, so a single instance can be registered as a singleton:
services.AddSingleton<INumberToWordsConverter>(_ => new NumberToWordsConverter("tr-TR"));
Localizations are parsed once per culture and cached for the process, so the extension methods are cheap too; reusing a converter is a small extra saving rather than a requirement.
If you pass your own LocalizationModel, the converter keeps a reference rather than a copy — do not mutate the model afterwards.
Precision and rounding
- The fractional part is rounded to
settings.decimalPlacesdigits (2 by default) usingMidpointRounding.AwayFromZero, which is what money expects:1.005becomes one dollar one cent, not zero cents. - Digits beyond that precision are rounded away, not truncated:
1.234567becomes twenty-three cents,1.235becomes twenty-four. - A fraction that rounds up carries into the whole part:
0.999becomes "ONE DOLLAR ZERO CENTS". decimalPlacesaccepts 0 through 6. Use 0 for currencies without a minor unit, 3 for the Tunisian dinar. With 0, the format strings must not reference{decimal}or{minor}— validation enforces this, because they would print the zero word on every amount.- The fraction is read as a number in its own right, so it needs scale words of its own: one per three decimal places.
decimalPlacesof 4 or more therefore requires at least two entries innumbers.scales. Validation enforces this too, because otherwise1.1234failed at conversion time with "the number is too large" — blaming a whole part of 1.
By default ConvertWithoutCurrency reads the fraction the way money is read, so 1.5 is "ONE POINT FIFTY" (fifty hundredths). Set "decimalReading": "Digits" in a locale to read it digit by digit instead — 1.5 becomes "ONE POINT FIVE" and 1.25 becomes "ONE POINT TWO FIVE".
Range
The largest convertible value is determined by the number of scale words a locale defines:
| Locale | Scale words | Largest value |
|---|---|---|
en-US, tr-TR, fr-FR, de-DE |
6 | 10^18 − 1 |
es-ES, ru-RU |
5 | 10^15 − 1 |
pt-PT |
3 | 10^9 − 1 |
Spanish and Portuguese stop earlier because their next scale has no single-word name — see Known limitations. Anything larger, including decimal.MaxValue, throws NumberOutOfRangeException rather than producing a wrong answer.
Error handling
Every failure is a NumWordifyException:
| Exception | Raised when |
|---|---|
LocalizationNotFoundException |
No localization resolves for the requested culture. Carries Culture and AvailableCultures. |
AmbiguousCurrencyException |
The culture resolved to another region's localization, so its default currency cannot be assumed. Carries RequestedCulture and ResolvedCulture. |
InvalidLocalizationException |
A localization is incomplete or inconsistent. The message names the offending JSON path. |
NumberOutOfRangeException |
The number needs more scale words than the locale defines. |
Argument mistakes (null culture, null model, unknown currency code, empty culture name) surface as ArgumentNullException / ArgumentException as usual.
Supported cultures
| Culture | Language | Default currency | Also defines | Notable rules handled |
|---|---|---|---|---|
en-US |
English | USD | EUR, GBP, TRY | Teens, hyphenated compounds, singular/plural currency |
tr-TR |
Turkish | TRY | EUR, USD, GBP | "BİN" rather than "BİR BİN" |
fr-FR |
French | EUR | USD, CHF | 70–99 vigesimal forms, cent/vingt plural including the adjective/noun split, plural scale words |
es-ES |
Spanish | EUR | USD, MXN | CIEN/CIENTO, fused twenties, apocope, plural scale words, de before a currency name |
pt-PT |
Portuguese | EUR | USD, BRL | CEM/CENTO, the E conjunction inside a group and — conditionally — before the last group, de before a currency name |
ru-RU |
Russian | RUB | USD, EUR | Three grammatical numbers selected on the last digits, and numerals that agree in gender with the scale word or currency unit after them |
de-DE |
German | EUR | CHF, USD | Inverted last two digits (EINUNDZWANZIG), everything below a million written as one word, EINS/EIN/EINE by what follows |
pt-PT |
Portuguese | EUR | USD, BRL | CEM/CENTO, the E conjunction inside a group and — conditionally — before the last group, de before a currency name |
tr-TR-EUR also ships, but is deprecated: it is excluded from SupportedCultures, is never chosen by language fallback, and resolves only when named exactly. Its output is identical to ToWords("tr-TR", "EUR"), which a test enforces. Use the currency code instead.
Known limitations
- French does not insert
de/d'between a noun scale word and a currency name:1_000_000M.ToWords("fr-FR")yields "UN MILLION EUROS" where correct French is "un million d'euros". The elision depends on the following word, which the template model cannot express. Supply your owncurrencyFormat, or post-process, if you need it. Spanish, where no elision occurs, is handled: "UN MILLÓN DE EUROS". - Spanish stops at 10^15 − 1.
MILLARDO(10^9) is accepted by the RAE but uncommon — "mil millones" is the usual form and cannot be expressed as a single scale word here. 10^15 has no accepted single word at all, so the scale is not defined rather than invented. Gender agreement (DOSCIENTAS) is not modelled. - Portuguese stops at 10^9 − 1. European Portuguese reads 10^9 as mil milhões, two words with the "um" dropped, and the scale table holds one word per step with no way to drop it — defining
MIL MILHÕESwould give "UM MIL MILHÕES" for 10^9 itself. The scale is left undefined rather than made wrong. Brazilian bilhão is a different value and would not be a fix. - Arabic-style duals are not expressible.
pluralRulecovers two families —OneOtherandEastSlavic(one/few/many, selected onn % 10andn % 100, which also serves Ukrainian and Belarusian) — but there is noTwocategory, so Arabic needs one that does not exist yet. Adding a family is a code change, deliberately: a rule expressed in JSON could not be validated up front the way the rest of the schema is. - French elision (
d'euros) is still not expressible, and plural categories did not help: elision depends on the sound of the following word, not on the count. - Word order within a group is hundreds → tens → ones, or hundreds → ones → tens with
settings.onesBeforeTensfor German. No locale needs a third order, but one that did could not express it. - Ordinals ("twenty-first") are out of scope.
Custom localization
Build a model in code for any language and currency:
using NumWordify.Extensions;
using NumWordify.Models;
var japanese = new LocalizationModel
{
Currencies = new Dictionary<string, CurrencyModel>
{
["JPY"] = new() { Major = "YEN", Minor = "SEN" },
},
DefaultCurrency = "JPY",
Numbers = new NumbersModel
{
Ones = ["", "ICHI", "NI", "SAN", "YON", "GO", "ROKU", "NANA", "HACHI", "KYU"],
Tens = ["", "JU", "NIJU", "SANJU", "YONJU", "GOJU", "ROKUJU", "NANAJU", "HACHIJU", "KYUJU"],
Hundreds =
[
"", "HYAKU", "NIHYAKU", "SANBYAKU", "YONHYAKU",
"GOHYAKU", "ROPPYAKU", "NANAHYAKU", "HAPPYAKU", "KYUHYAKU"
],
Scales = ["", "SEN", "MAN", "OKU", "CHO", "KEI"],
},
Settings = new SettingsModel
{
SkipOneForThousand = true,
NegativeWord = "MAINASU",
ZeroWord = "ZERO",
CurrencyFormat = "{whole} {major}",
NumberFormat = "{whole} TEN {decimal}",
},
};
1234.56M.ToWords(japanese);
// "SEN NIHYAKU SANJU YON YEN"
Incomplete models are rejected at construction time with a message naming the missing field, so a broken localization never reaches the conversion loop.
Adding a new language
Drop a JSON file into Resources/. The file name is the culture name. This block is parsed by a test, so it is always valid:
{
"defaultCurrency": "USD",
"currencies": {
"USD": {
"major": "DOLLARS",
"majorSingular": "DOLLAR",
"minor": "CENTS",
"minorSingular": "CENT"
},
"EUR": {
"major": "EUROS",
"majorSingular": "EURO",
"minor": "CENTS",
"minorSingular": "CENT"
}
},
"settings": {
"skipOneForThousand": false,
"useTeens": true,
"negativeWord": "NEGATIVE",
"zeroWord": "ZERO",
"currencyFormat": "{whole} {major} {decimal} {minor}",
"numberFormat": "{whole} POINT {decimal}",
"decimalPlaces": 2
},
"numbers": {
"ones": ["", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE"],
"tens": ["", "TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY", "SEVENTY", "EIGHTY", "NINETY"],
"hundreds": [
"", "ONE HUNDRED", "TWO HUNDRED", "THREE HUNDRED", "FOUR HUNDRED",
"FIVE HUNDRED", "SIX HUNDRED", "SEVEN HUNDRED", "EIGHT HUNDRED", "NINE HUNDRED"
],
"scales": ["", "THOUSAND", "MILLION", "BILLION", "TRILLION", "QUADRILLION"]
},
"specialNumbers": {
"teens": [
"ELEVEN", "TWELVE", "THIRTEEN", "FOURTEEN", "FIFTEEN",
"SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN"
],
"compoundSeparator": "-"
}
}
Then approve the snapshot: run the test suite with NUMWORDIFY_APPROVE=1, which writes tests/NumWordify.Tests/Approvals/<culture>.approved.txt — every value from 0 to 1000 plus a magnitude ladder, with and without currency. Read that file before committing it; it is the review.
Schema reference
numbers
| Field | Required | Meaning |
|---|---|---|
ones, tens, hundreds |
yes | Exactly ten entries, indexed by digit; index 0 is unused and must be empty. |
exactHundreds |
no | Hundreds words used when the last two digits are zero. Ten entries, but only the ones that differ need a value — Spanish fills CIEN at index 1 and leaves the rest empty. |
scales |
yes | Index 0 is the units group, 1 the thousands, and so on. Index 0 must be empty; every other entry must have a value. Length caps the convertible range at 10^(3 × length) − 1. |
scalesPlural |
no | Scale words used when the preceding group is greater than one (DEUX MILLIONS). Same length as scales; empty entries fall back. |
scaleKinds |
no | "Adjective" or "Noun" per scale word, same length as scales. Defaults to all Adjective. This is what distinguishes French DEUX CENT MILLE from DEUX CENTS MILLIONS. |
scaleForms |
no | Scale words per grammatical number, keyed "One", "Few", "Many", "Other", each array the same length as scales. Only for locales whose pluralRule has more than two forms — Russian ТЫСЯЧА / ТЫСЯЧИ / ТЫСЯЧ. Empty entries fall back to scalesPlural, then scales. |
scaleGenders |
no | "Masculine", "Feminine" or "Neuter" per scale word, same length as scales. Defaults to all masculine. Only meaningful with specialNumbers.byGender. |
settings
| Field | Default | Meaning |
|---|---|---|
skipOneForThousand |
false |
Drop the word for "one" before the thousands scale word (BİN, MILLE). |
useTeens |
auto | Use specialNumbers.teens for 11–19. Left unset it turns itself on whenever teens is supplied. |
useExactHundredsBeforeScale |
true |
Whether exactHundreds also applies before an Adjective scale word. Before a Noun scale word the exact form is always used. Spanish CIEN MIL keeps it on; French DEUX CENT MILLE turns it off. |
apocopateBeforeNoun |
false |
Apply specialBeforeScale in front of a noun — a Noun scale word or a currency name (Spanish UN MILLÓN, UN EURO). |
pluralRule |
"OneOther" |
How a count selects a grammatical number. "OneOther" is two forms; "EastSlavic" is three, chosen on n % 10 and n % 100 (Russian, Ukrainian, Belarusian). |
onesBeforeTens |
false |
Read the last two digits backwards: German EINUNDZWANZIG, "one and twenty". The separator is still compoundSeparator. |
adjectiveScaleSeparator |
" " |
What goes on either side of an Adjective scale word. German sets "", which is what writes everything below a million as one word; a Noun scale word always takes a space. |
nounScaleLinkWord |
— | Word inserted between the number and the currency name when the number ends in a Noun scale word (Spanish UN MILLÓN DE EUROS). |
hundredsSeparator |
" " |
What goes between the hundreds word and the rest of the same group (Portuguese CENTO E VINTE; Spanish leaves it a space, CIENTO VEINTE). |
finalGroupSeparator |
— | What goes in front of the last group when that group is a single term — below one hundred, or a whole number of hundreds. The only setting whose effect depends on the value: Portuguese needs MIL E OITOCENTOS (1800) but MIL OITOCENTOS E NOVENTA E DOIS (1892). |
negativeWord, zeroWord |
— | Required. |
currencyFormat |
— | Required. Placeholders: {whole}, {major}, {decimal}, {minor}. Must contain {whole}; unknown placeholders are rejected. |
numberFormat |
— | Required. Placeholders: {whole}, {decimal}. |
decimalPlaces |
2 |
Fractional digits kept, 0 through 6. Needs one scales entry per three digits, since the fraction is read as a number. |
decimalReading |
Fraction |
Fraction or Digits; see Precision and rounding. |
specialNumbers
| Field | Meaning |
|---|---|
teens |
Exactly nine entries, for 11 through 19. |
special |
Whole-word overrides for the last two digits of a group, keyed 1–99. This is where French 70–99 and Spanish 21–29 live. |
specialBeforeScale |
Overrides that apply in front of an Adjective scale word, and — with apocopateBeforeNoun — in front of a noun. |
byGender |
Numeral forms that agree with the gender of the word they stand in front of, keyed by gender and then by the last two digits. Russian ОДНА ТЫСЯЧА but ОДИН МИЛЛИОН. Consulted before specialBeforeScale, and only when the following word declares a gender. |
compoundSeparator |
Placed between the tens and ones word. "-" for English, " Y " for Spanish, " " (the default) for Turkish. |
Top level
| Field | Meaning |
|---|---|
currencies |
Currencies this locale can name, keyed by ISO 4217 code. |
defaultCurrency |
Key into currencies naming the one Convert uses when nothing overrides it. A locale that names a single currency still lists it here. |
deprecated |
Excludes the locale from SupportedCultures and from language fallback. It still resolves when named exactly. |
Templates are expanded in a single pass, so a currency name that happens to contain {minor} is emitted literally rather than being treated as another placeholder. A placeholder that resolves to an empty string takes its preceding space with it; whitespace a locale wrote on purpose is left alone.
Migrating from 1.x
Version 2.0 changes output for four of the five shipped locales, because that output was wrong. Re-check any golden files or stored strings.
- The ones digit is no longer dropped.
1234.56M.ToWords("tr-TR")was "BİN İKİ YÜZ OTUZ TL ELLİ Kr" and is now "BİN İKİ YÜZ OTUZ DÖRT TL ELLİ ALTI Kr". The same fix applies tofr-FRandes-ES. - Round hundreds no longer gain a trailing "ZERO" in
en-US:100Mwas "ONE HUNDRED ZERO USD ZERO Cents", now "ONE HUNDRED DOLLARS ZERO CENTS". en-UScurrency names changed fromUSD/CentstoDOLLARS/CENTS, with singular forms.- French and Spanish are now grammatically correct for 0–99, for the
cent/cientoforms and for scale agreement; almost every value in those languages changes. - Rounding is away from zero rather than to even, so some values gain a minor unit.
NumberToWordsConverteris nowsealed. Code that derived from it will not compile; depend onINumberToWordsConverterinstead.- Exceptions moved to the
NumWordify.Exceptionsnamespace.FileNotFoundExceptionbecameLocalizationNotFoundExceptionand mostInvalidOperationExceptioncases becameInvalidLocalizationException; both derive fromNumWordifyExceptionand neither derives from the old types, so 1.xcatchblocks stop matching. - A culture that resolves through language fallback no longer borrows the locale's default currency —
ToWords("es-MX")now throwsAmbiguousCurrencyExceptioninstead of silently printing euros. tr-TR-EURis no longer listed inSupportedCulturesand is never chosen by fallback, though naming it exactly still works.settings.useCompoundNumbersandsettings.skipOneForHundredare gone. They stopped having any effect and were removed here rather than left as dead properties for the life of 2.x. The separator comes fromspecialNumbers.compoundSeparator; the hundreds wording comes fromnumbers.hundreds[1]. The JSON keys are ignored on load, so a 1.x locale file still parses.settings.useTeensis nowbool?. Assignments still compile; comparisons such as== truestill work.LocalizationModel.Currencyis gone. A locale names its currencies incurrenciesand points at one withdefaultCurrency; there is no second place to spell the default out. TheLocalizationModel(currency, numbers, settings)constructor still takes aCurrencyModeland files it under the keyLocalizationModel.DefaultCurrencyKey.LocalizationModel.Numbersis now nullable, which is what it always was at runtime.
Project structure
NumWordify/
├── Converters/
│ ├── INumberToWordsConverter.cs # Public conversion contract
│ ├── LocalizationLoader.cs # Embedded resource lookup, parsing, caching
│ ├── LocalizationValidator.cs # Fail-at-construction validation
│ └── NumberToWordsConverter.cs # Conversion algorithm
├── Exceptions/
│ └── NumWordifyException.cs # Exception hierarchy
├── Extensions/
│ └── DecimalExtensions.cs # Extension methods for decimal
├── Models/ # Localization data model + WordifyOptions
└── Resources/ # en-US, tr-TR, tr-TR-EUR, fr-FR, es-ES, pt-PT, ru-RU
docs/
└── word-forms-3.0.md # Design note: why the schema has three ways to
# name a word form, and when to reduce it to one
tests/
└── NumWordify.Tests/
├── Approvals/ # Full-output snapshots, one file per locale
└── *.cs # Golden tables, concurrency, validation, schema
Requirements
.NET 6.0 or later, or any runtime supporting .NET Standard 2.0 (including .NET Framework 4.6.1+).
Contributing
Contributions are welcome. A pull request that changes conversion output must come with the regenerated snapshot, and the diff has to be readable line by line.
Building needs the .NET 9 SDK or newer — global.json sets 9.0.100 as the floor and rolls forward to the newest installed major, so a newer SDK needs no edit. Which analyzer warnings fire is pinned by AnalysisLevel in Directory.Build.props, not by the SDK you happen to have.
The test suite runs one leg per shipped target framework, so it additionally needs the .NET 6, 7 and 8 runtimes installed, and on Windows the .NET Framework 4.8 targeting pack. That is deliberate: every framework the package ships is executed, not merely compiled. dotnet test -f net9.0 is enough while iterating.
- Add support for new languages
- Improve existing language support
- Fix bugs
- Improve documentation
License
MIT — see LICENSE.
Author
Kadir Emre Parlak — @kep_dev
Support
- Check the GitHub Issues
- Open a new issue if yours is not there
- For usage questions, include the culture, the input value and the output you got
Changelog
See CHANGELOG.md.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- System.Text.Json (>= 8.0.5)
-
net6.0
- No dependencies.
-
net7.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
See CHANGELOG.md for release notes.