Java object-oriented library for converting numbers into text

Numbify is a Java object-oriented library for converting numbers into text with extensive customization options. There are two ways to use it:

  • NumbifyBuilder: Traditional builder pattern.
  • Object Composition: Object oriented way.

Objects example

For advanced customization, Numbify allows direct object composition following the decorator pattern. This approach provides granular control over number formatting by combining specialized components. Minimal example:

Objects
Builder
Numbify ru = new Numbify(
    new Russian(Currency.NUMBER),
    new IntText(new Text()) // just int text
);
ru.toText(123.12); // сто двадцать три
Not possible

To include currency text in your output, wrap the IntText component with IntCurrencyText:

Objects
Builder
Numbify ru = new Numbify(
    new Russian(Currency.NUMBER),
    new IntCurrencyText(new IntText(new Text())) // just int text with currency
);
ru.toText(123.12); // сто двадцать три целых
Not possible

Next, you need decimals also. Same principle as for integers, use DecimalText, or DecimalCurrencyText and combine the result with CombinedText:

Objects
Builder
Numbify ru = new Numbify(
    new Russian(Currency.NUMBER),
    new CombinedText(
        new IntCurrencyText(new IntText(new Text())),
        new DecimalCurrencyText(new DecimalText(new Text()))
    )
);
ru.toText(123.12); // сто двадцать три целых двенадцать сотых
Numbify en = new NumbifyBuilder()
    .russian(Currency.NUMBER)
    .build();
en.toText(); // сто двадцать три целых двенадцать сотых

Use IntOriginalText or DecimalOriginalText to maintain original numeric values in specific portions of the output text:

Objects
Builder
Numbify ru = new Numbify(
    new Russian(Currency.NUMBER),
    new CombinedText(
        new IntCurrencyText(new IntText(new Text())),
        new DecimalCurrencyText(new DecimalOriginalText()) // use original decimal
    )
);
ru.toText(123.12); // сто двадцать три целых 12 сотых
Numbify en = new NumbifyBuilder()
    .russian(Currency.NUMBER)
    .originalDecimal()
    .build();
en.toText(); // сто двадцать три целых 12 сотых

Finally, wrap combined text with CapitalizedText:

Objects
Builder
Numbify ru = new Numbify(
    new Russian(Currency.NUMBER),
    new CapitalizedText(
        new CombinedText(
            new IntCurrencyText(new IntText(new Text())),
            new DecimalCurrencyText(new DecimalOriginalText())
        )
    )
);
ru.toText(123.12); // Сто двадцать три целых 12 сотых
Numbify en = new NumbifyBuilder()
    .russian(Currency.NUMBER)
    .originalDecimal()
    .capitalize()
    .build();
en.toText(); // Сто двадцать три целых 12 сотых

Use NegativeSignText to translate ‘-‘ to text:

Objects
Builder
Numbify en = new Numbify(
    new English(Currency.USD, "and"),
    new CapitalizedText(
            new NegativeSignText(    // convert negative sign to text
                    new CombinedText(
                            new IntCurrencyText(new IntText(new Text())),
                            new DecimalCurrencyText(new DecimalOriginalText())
                    )
            )
    )
);
en.toText(-123.12); // Negative one hundred twenty-three dollars and 12 cents
Numbify en = new NumbifyBuilder()
    .english(Currency.USD, "and")
    .originalDecimal()
    .capitalize()
    .negativeSign()
    .build();
en.toText(); // Negative one hundred twenty-three dollars and 12 cents

There is also a possibility to convert number digit by digit using DigitByDigitText:

Objects
Builder
Numbify en = new Numbify(
    new English(Currency.NUMBER, "point"),
    new CapitalizedText(
            new CombinedText(
                    new IntCurrencyText(new IntText(new Text())),
                    new DecimalText(new DigitByDigitText())
            )
    )
);
en.toText(1.122); // One point one two two
Not possible

NumbifyBuilder

List of option methods available in builder:

Numbify en = new NumbifyBuilder()
    .english(Currency.USD)
    .hideIntCurrency()     // hide currency text for integer part of the number
    .hideDecimalCurrency() // hide currency text for decimal part
    .originalInt()         // do not convert integer part, leave it as number
    .originalDecimal()     // do not convert decimal part
    .negativeSign()        // convert negative sign '-' to text representation
    .digitByDigitDecimal() // convert decimal part digit by digit like 1.25 -> "one point two five"
    .capitalize()          // print text with capital letter
    .build();

Simple usage:

Builder
Objects
Numbify en = new NumbifyBuilder()
    .english(Currency.USD)
    .build();
String numberInText = en.toText(25.17); // "twenty-five dollars seventeen cents"
Numbify en = new Numbify(
    new English(Currency.USD),
    new CombinedText(
        new IntCurrencyText(new IntText(new Text())),
        new DecimalCurrencyText(new DecimalText(new Text()))
    )
);
en.toText(25.17); // "twenty-five dollars seventeen cents"

More complex example:

Builder
Objects
Numbify en = new NumbifyBuilder()
    .english(Currency.NUMBER, "point")
    .digitByDigitDecimal()
    .hideDecimalCurrency()
    .capitalize()
    .build();

String numberInText = en.toText(25.177); // "Twenty-five dollars point one seven seven"
Numbify numbify = new Numbify(
    new English(Currency.NUMBER, "point"),
    new CapitalizedText(
        new CombinedText(
            new IntCurrencyText(new IntText(new Text())),
            new DecimalText(new DigitByDigitText())
        )
    )
);
en.toText(25.177); // "Twenty-five dollars point one seven seven"

Language features

Some languages have grammatical features that affect how numbers are represented in text. For example, Russian uses declensions, so the builder includes an additional method to specify them:

Builder
Objects
Numbify ru = new NumbifyBuilder()
    .russian(RuDeclension.GENITIVE, Currency.RUB)
    .build();

String number = ru.toText(123.45); // "ста двадцати трёх рублей сорока пяти копеек"
Numbify ru = new Numbify(
    new Russian(RuDeclension.GENITIVE, Currency.RUB),
    new CombinedText(
        new IntCurrencyText(new IntText(new Text())),
        new DecimalCurrencyText(new DecimalText(new Text()))
    )
);
ru.toText(123.45); // "ста двадцати трёх рублей сорока пяти копеек"

English has option to customize separator between integer and decimal parts of the number:

Builder
Objects
Numbify en = new NumbifyBuilder()
    .english(Currency.USD, "and") // "and" as decimal separator
    .build();
String numberInText = en.toText(25.17); // "twenty-five dollars and seventeen cents"
Numbify en = new Numbify(
    new English(Currency.USD, "and"),
    new CombinedText(
        new IntCurrencyText(new IntText(new Text())),
        new DecimalCurrencyText(new DecimalText(new Text()))
    )
);
en.toText(25.17); // "twenty-five dollars and seventeen cents"

Schema of Classes

Supported Number Types

Numbify supports any Java numeric data types that are subclasses of Number:

Number
 ├── Byte
 ├── Short
 ├── Integer
 ├── Long
 ├── Float
 ├── Double
 ├── BigInteger
 └── BigDecimal