Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

154
Vistas
It it possible to have multiple Locales in one same MessageFormat?

I have the following JSON example below:

{
    "value": 946.2,
    "description": "O valor é R$ 946,20."
}

I need to use MessageFormat to JUnit test this JSON example, but I get an invalid value because my Locale is not in english. If I change my Locale to english instead of brazilian portuguese I get an invalid description because the currency value is displayed in English.

Here's my code:

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.Locale;

Locale.setDefault(Locale.ENGLISH);

System.out.println(MessageFormat.format("""
'{'
    "value": {0},
    "description": "O valor é {0,number,currency}."
'}'
""", new BigDecimal(946.2)));

How can I format the value or the description in order to get the JSON as displayed above?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Sure, no problem! But:

  • Locale.setDefault is harsh! (for test it can be tolerable.... but i don't want to look up that bug..)
  • (I "don't like" MessageFormat... it uses StringBuffer internally(Mr. performance killer & memory dumper).)

As long as you can handle the "complexity", it can be done like:

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.Locale;

public class MainSimple {

  // Brazilian Locale:
  private static final Locale LOCALE_PT_BR = new Locale.Builder().
      setLanguage("pt").
      setRegion("BR").
      build();
  // US number format:
  private static final NumberFormat DEFAULT_NUMBER_FMT = NumberFormat.getNumberInstance(Locale.US);

  public static void main(String[] args) {
    // MessageFormat instance, with format (with 2! parameters) and Locale:
    MessageFormat mainFmt = new MessageFormat("""
                      '{'
                          "value": {0},
                          "description": "O valor é {1,number,currency}. <-- trick 1 "
                      '}'
                      """, LOCALE_PT_BR);
    
    final BigDecimal num = new BigDecimal(946.2);
    // trick 2:
    Object[] params = {DEFAULT_NUMBER_FMT.format(num), num};
    // do it:
    System.out.println(mainFmt.format(params));
  }
}

Outline:

  • Constants for:
    • Brazilian (outer format) locale.
    • US/Standard (inner) number format for custom (non brazilian) formatting/this particular number.
  • MessageFormat has a constructor with locale parameter! (we use that, and call it outer format/locale(mainFmt))
  • Int the format we "trick a little" and use 2 parameters: {0} and {1,number,currency}
  • We trick on: Pass the first parameter as a (US-formatted number) String, the second as had. (Object[] params = {DEFAULT_NUMBER_FMT.format(num), num})
  • finally format (& print to out).

Prints:

{
    "value": 946.2,
    "description": "O valor é R$ 946,20."
}
over 4 years ago · Santiago Trujillo Denunciar

0

This is a String.format solution with two inner (localized, customized) NumberFormatters:

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Locale;

public class OtherMain {

  private static final Locale LOCALE_PT_BR = new Locale.Builder().
      setLanguage("pt").
      setRegion("BR").
      build();
  
  private static final NumberFormat DEFAULT_NUMBER_FMT
      = NumberFormat.getNumberInstance(Locale.US);
  private static final NumberFormat MY_SPECIAL_NUMBER_FMT
      = NumberFormat.getCurrencyInstance(LOCALE_PT_BR);

  static {
    // this disables "thousands sperarator", we can adjust DEFAULT_NUMBER_FMT as well...
    MY_SPECIAL_NUMBER_FMT.setGroupingUsed(false);
  }

  public static void main(String[] args) {
    final BigDecimal num = new BigDecimal(99946.2);
    System.out.format("""
                      {
                        "value": %s,
                        "description": "O valor é %s."
                      }
                      """,
        DEFAULT_NUMBER_FMT.format(num),
        MY_SPECIAL_NUMBER_FMT.format(num)
    );
  }
}

Prints:

{
  "value": 99,946.2,
  "description": "O valor é R$ 99946,20."
}
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda