Skip to content

Dinero y Java: La introducción en JodaMoney

Hola a todos! En este articulo vamos a hablar sobre dinero en Java. Este artículo es la traducción – puedes leer el articulo original aqui. Es un hecho que normalmente usamos BigDecimal para hacer cálculos con dinero. Pero, es verdad, que Java carece del API incorporado para trabajar con dinero. En este caso, podemos usar JodaMoney. De esta manera, hoy vamos a describir como hacer cálculos con dinero en Java gracias a esta biblioteca. Ahora, ponemos manos a la obra!

Creamos Money

Primero lo primero, necesitamos obtener la instancia de Money. Money se refiere a un contenedor para guardar la información sobre dinero: la cantidad y la moneda. Esta clase es inmutable. JodaMoney nos ofrece algunas formas para conseguir esta tarea:

Desde java.util.String

Esta manera me parece más fácil que otras. Necesitamos el String que tiene un formato adecuado:

[MMM] [cantidad]

MMM significa la moneda en el formato internacional, por ejemplo, EUR por euros o USD por dollares norteamericanos.

Como ejemplo, podemos observar este codigo:

Money euros = Money.parse("EUR 100.00");
System.out.println(euros);

// EUR 100.00

Cuando JodaMoney no puede comprender String, va a lanzar la excepción IllegalArgumentException.

Desde un valor cero

Otra manera popular es crear Money desde un valor (una cantidad de dinero) cero con la moneda especificada. Por ejemplo, podemos observar este código:

Money zeros = Money.zero(CurrencyUnit.EUR);
System.out.println(zeros);

// EUR 0.00

Como puedes observar, necesitas a sumunistar CurrencyUnit. Esta clase se refiere a la moneda, por ejemplo euros o dollares norteamericanos. Hay el set de las monedas predefinidas – EUR, GBP, USD etc. Puedes definir tus propias monedas con una modificación del archivo /org/joda/money/MoneyData.csv. Hay mas información sobre monedas alli.

Desde BigDecimal y moneda

La ultima opción es crear la instancia de Money con un valor de BigDecimal y la moneda:

Money fromBigDecimal = Money.of(CurrencyUnit.EUR, new BigDecimal("100.00"));
Money fromString = Money.parse("EUR 100.00");
boolean areEquals = fromBigDecimal.isEqual(fromString);
System.out.pritnln(areEquals);

//true

Después, observamos qué diferecia hay entre Major y Minor partes de Money.

¿Qué significan Major y Minor?

En Javadoc casi todos métodos aritméticos tienen dos versiones: para Mayor y para Minor. Por ejemplo, plusMajor() y plusMinor(). ¿Qué diferencia hay entre ellos? Me explico. Dinero tiene dos partes – podemos observar el dibujo:

En otras palabras, Minor es una parte decimal. Las partes están divido por punto. Podemos hacer cálculos en una manera independiente con cada parte, por ejemplo:

Money money = Money.parse("USD 1000.00");
Money major = money.plusMajor(500L);
System.out.println(major);
// output: USD 1500.00

Money minor = money.plusMinor(50L);
System.out.println(minor);
// output: USD 1000.50

En la proxima parte de articulo vamos a ver como hacer la aritmética básica con JodaMoney.

La aritmética básica

JodaMoney nos permite hacer cálculos basicos con dinero: adición, sustracción, multiplicación y división.

Adición

Para sumar dos instancias de dinero, usamos el método que se llama plus():

Money euros10 = Money.parse("EUR 10.00");
Money euros15 = Money.parse("EUR 15.00");
Money addition = euros10.plus(euros15);
System.out.println(addition);
// output: EUR 25.00

Sustracción

El método minus() nos permite obtener una diferencia entre dos valores:

Money dollars16 = Money.of(CurrencyUnit.USD, 16.00);
Money dollars14 = Money.of(CurrencyUnit.USD, new BigDecimal("14.00"));
Money subtraction = dollars16.minus(dollars14);
System.out.println(subtraction);
// output: USD 2.00

Multiplicación

JodaMoney nos ofrece los métodos para multiplicar dinero – multipliedBy():

  • multipliedBy(BigDecimal, RoundingMode)
  • multipliedBy(long)
  • multiplied(double, RoundingMode)

Entonces, hay varios metodos por eso. La diferencia es que podemos usar cualquiera de los dos: un valor en long o un valor y RoundingMode. La ultima opción tiene tambien la información como redondear un resultado. Java.Math nos ofrece varias opciones del redondeo:

  1. RoundingMode.UP = redondea cualquier decimal a su entero superior
  2. RoundingMode.DOWN = redondea el decimal a 0.
  3. RoundingMode.CEILING = para un valor positivo actua igual que RoundingMode.UP y para un valor negativo actua igual que RoundingMode.DOWN
  4. RoundingMode.FLOOR = para un valor positivo actua igual que RoundingMode.DOWN y para un valor negativo actua igual que RoundingMode.UP
  5. RoundingMode.HALF_DOWN = redondea hacia arriba solo si el decimal es > a 0.5
  6. RoundingMode.HALF_EVEN = redondea hacia arriba solo si su numero mas cercano a la izquierda es impar
  7. RoundingMode.UNNECESSARY = para insistir que un valor no necesita redonde, esto solo ocurre cuando el valor no tiene decimales

Mas información sobre RoundingMode en Java hay en este articulo.

Por ejemplo:

Money pouns15 = Money.of(CurrencyUnit.GBP, 15.00);
Money multiplication = pounds15.multipliedBy(2L);
System.out.println(multiplication);
// output: GBP 30.00

División

La ultima operación que observamos es la división. Parecido a la multiplicación hay diferentes formas:

  • dividedBy(double, RoundingMode)
  • dividedBy(long, RoundingMode)
  • dividedBy(BigDecimal, RoundingMode)

Aqui, como podemos constatar, todos métodos exigen RoundingMode. Por ejemplo:

Money francs30 = Money.parse("CHF 30.00");
Money division = francs30.dividedBy(2.0d, RoundingMode.HALF_EVEN);
System.out.println(division);

Y la ultima cosa, que me gustaría observar es la situación cuando tenemos dos instancias de Money en diferentes monedas. Puedes observar un código:

Money francs10 = Money.parse("CHF 10.00");
Money euros10 = Money.parse("EUR 10.00");
Money result = francs10.plus(euros10);

Pues, en este caso, JodaMoney va a lanzar una CurrencyMismatchException.

La conclusión

Vale, en este articulo hemos observado los principios generales de la biblioteca JodaMoney. Es la biblioteca muy útil para hacer cálculos con dinero en la manera sencilla y rápida en Java. Si tienes preguntas, puedes comentar este articulo o enviarme un mensaje en Twitter. Nos vemos!

La bibliografía

  • Alexis Lopez. JSR 354: API para trabajar con valores monetarios en aplicaciones Java (2015), Oracle Technology Network leer aqui
  • Como redondear decimales en Java (2012). leer aqui
  • Yuri Mednikov. Working with money in Java: a quick introduction to JodaMoney library (2019), Dev.to leer aqui