Affichage des montants en mots

Affichage des montants d'argent en mots

1. Vue d'ensemble

Dans ce didacticiel, nous allons voir comment nous pouvons convertir un montant monétaire en représentation de mots en Java.

Nous verrons également à quoi pourrait ressembler une implémentation personnalisée, via une bibliothèque externe -Tradukisto.

2. la mise en oeuvre

Commençons par notre propre implémentation. The first step is to declare two String arrays avec les éléments suivants:

public static String[] ones = {
  "", "one", "two", "three", "four",
  "five", "six", "seven", "eight",
  "nine", "ten", "eleven", "twelve",
  "thirteen", "fourteen", "fifteen",
  "sixteen", "seventeen", "eighteen",
  "nineteen"
};

public static String[] tens = {
  "",          // 0
  "",          // 1
  "twenty",    // 2
  "thirty",    // 3
  "forty",     // 4
  "fifty",     // 5
  "sixty",     // 6
  "seventy",   // 7
  "eighty",    // 8
  "ninety"     // 9
};

Lorsque nous recevons une entrée, nous devons gérer les valeurs non valides (valeurs nulles et négatives). Once a valid input is received, we can extract the number of dollars and cents into variables:

 long dollars = (long) money;
 long cents = Math.round((money - dollars) * 100);

Si le nombre donné est inférieur à 20, alors nous obtiendrons l'élémentones' approprié du tableau en fonction de l'index:

if (n < 20) {
    return ones[(int) n];
}

Nous utiliserons une approche similaire pour les nombres inférieurs à 100, mais maintenant nous devons également utiliser le tableautens:

if (n < 100) {
    return tens[(int) n / 10]
      + ((n % 10 != 0) ? " " : "")
      + ones[(int) n % 10];
}

Nous procédons de la même manière pour les nombres inférieurs à mille.

Ensuite, nous utilisons des appels récursifs pour traiter les numéros inférieurs à un million, comme indiqué ci-dessous:

if (n < 1_000_000) {
    return convert(n / 1000) + " thousand" + ((n % 1000 != 0) ? " " : "")
      + convert(n % 1000);
}

La même approche est utilisée pour les chiffres inférieurs à un milliard, et ainsi de suite.

Voici la méthode principale pouvant être appelée pour effectuer cette conversion:

 public static String getMoneyIntoWords(double money) {
    long dollars = (long) money;
    long cents = Math.round((money - dollars) * 100);
    if (money == 0D) {
        return "";
    }
    if (money < 0) {
        return INVALID_INPUT_GIVEN;
    }
    String dollarsPart = "";
    if (dollars > 0) {
        dollarsPart = convert(dollars)
          + " dollar"
          + (dollars == 1 ? "" : "s");
    }
    String centsPart = "";
    if (cents > 0) {
        if (dollarParts.length() > 0) {
            centsPart = " and ";
        }
        centsPart += convert(cents) + " cent" + (cents == 1 ? "" : "s");
    }
    return dollarsPart + centsPart;
}

Testons notre code pour nous assurer qu'il fonctionne:

@Test
public void whenGivenDollarsAndCents_thenReturnWords() {
    String expectedResult
     = "nine hundred twenty four dollars and sixty cents";

    assertEquals(
      expectedResult,
      NumberWordConverter.getMoneyIntoWords(924.6));
}

@Test
public void whenTwoBillionDollarsGiven_thenReturnWords() {
    String expectedResult
      = "two billion one hundred thirty three million two hundred"
        + " forty seven thousand eight hundred ten dollars";

    assertEquals(
      expectedResult,
      NumberWordConverter.getMoneyIntoWords(2_133_247_810));
}

@Test
public void whenThirtyMillionDollarsGiven_thenReturnWords() {
    String expectedResult
      = "thirty three million three hundred forty eight thousand nine hundred seventy eight dollars";
    assertEquals(
      expectedResult,
      NumberWordConverter.getMoneyIntoWords(33_348_978));
}

Testons également certains cas extrêmes et nous assurons que nous les avons également couverts:

@Test
public void whenZeroDollarsGiven_thenReturnEmptyString() {
    assertEquals("", NumberWordConverter.getMoneyIntoWords(0));
}

@Test
public void whenNoDollarsAndNineFiveNineCents_thenCorrectRounding() {
    assertEquals(
      "ninety six cents",
      NumberWordConverter.getMoneyIntoWords(0.959));
}

@Test
public void whenNoDollarsAndOneCent_thenReturnCentSingular() {
    assertEquals(
      "one cent",
      NumberWordConverter.getMoneyIntoWords(0.01));
}

3. Utilisation d'une bibliothèque

Maintenant que nous avons mis en œuvre notre propre algorithme, effectuons cette conversion en utilisant une bibliothèque existante.

Tradukisto est une bibliothèque pour Java 8+, qui peut nous aider à convertir des nombres en leurs représentations de mots. Tout d'abord, nous devons l'importer dans notre projet (la dernière version de cette bibliothèque se trouvehere):


    pl.allegro.finance
    tradukisto
    1.0.1

Nous pouvons maintenant utiliser la méthodeasWords() deMoneyConverters pour effectuer cette conversion:

public String getMoneyIntoWords(String input) {
    MoneyConverters converter = MoneyConverters.ENGLISH_BANKING_MONEY_VALUE;
    return converter.asWords(new BigDecimal(input));
}

Testons cette méthode avec un cas de test simple:

@Test
public void whenGivenDollarsAndCents_thenReturnWordsVersionTwo() {
    assertEquals(
      "three hundred ten £ 00/100",
      NumberWordConverter.getMoneyIntoWords("310"));
}

Nous pourrions également utiliser la bibliothèqueICU4J pour ce faire, mais elle est volumineuse et est livrée avec de nombreuses autres fonctionnalités qui sortent du cadre de cet article.

Cependant, examinez-le si Unicode et la prise en charge de la mondialisation sont nécessaires.

4. Conclusion

Dans cet article rapide, nous avons vu deux approches sur la manière de convertir une somme d'argent en mots.

Le code de tous les exemples expliqués ici, et bien plus encore, peut être trouvéover on GitHub.