Search code examples
javajsonescapingjava-17messageformat

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?


Solution

  • 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."
    }