Adrian Schmid created FREEMARKER-125:
----------------------------------------

             Summary: ExtendedDecimalFormatParser ignores 
DecimalFormatSymbolsProvider
                 Key: FREEMARKER-125
                 URL: https://issues.apache.org/jira/browse/FREEMARKER-125
             Project: Apache Freemarker
          Issue Type: Bug
          Components: engine
    Affects Versions: 2.3.28, 2.3.29
            Reporter: Adrian Schmid
             Fix For: 2.3.29


We have customers that operate in multiple regions of Switzerland and use the 
locales de-CH, fr-CH and it-CH.

The standard fr-CH number format changed when we upgraded from java 8 to java 
11.

old:
 1'000.00 (single quote as thousands separator and dot as decimal separator)
 new:
 1 000,00 (nonbreaking space as thousands separator and comma as decimal 
separator)

To "fix" the issue we implemented a custom DecimalFormatSymbolsProvider to use 
the de-CH DecimalFormatSymbols for all swiss locales:
{code:java}
public class SwissDecimalFormatSymbolsProvider extends 
DecimalFormatSymbolsProvider {
    @Override
    public Locale[] getAvailableLocales() {
        return new Locale[] {
            Locale.forLanguageTag("de-CH"),
            Locale.forLanguageTag("fr-CH"),
            Locale.forLanguageTag("it-CH")
        };
    }

    @Override
    public DecimalFormatSymbols getInstance(Locale locale) {
        return new DecimalFormatSymbols(Locale.forLanguageTag("de-CH"));
    }
}
{code}
This works everywhere as expected except for when people use a "custom" 
freemarker number format.

E.g.
 number?currency -> 1'000.00 CHF (correct de-CH DecimalFormatSymbols)
 number?string(",##0.00") -> 1 000,00 (wrong fr-CH DecimalFormatSymbols)

I looked at the source code of the constructor of ExtendedDecimalFormatParser 
and DecimalFormatSymbols are "retrieved" by using the constructor of the 
DecimalFormatSymbols class.
{code:java}
private ExtendedDecimalFormatParser(String formatString, Locale locale) {
    src = formatString;
    this.symbols = new DecimalFormatSymbols(locale);
}
{code}
This initialises DecimalFormatSymbols for the current locale ("fr-CH") instead 
of applying DecimalFormatSymbolsProviders.
{code:java}
/**
 * Create a DecimalFormatSymbols object for the given locale.
 * This constructor can only construct instances for the locales
 * supported by the Java runtime environment, not for those
 * supported by installed
 * {@link java.text.spi.DecimalFormatSymbolsProvider 
DecimalFormatSymbolsProvider}
 * implementations. For full locale coverage, use the
 * {@link #getInstance(Locale) getInstance} method.
 * If the specified locale contains the {@link 
java.util.Locale#UNICODE_LOCALE_EXTENSION}
 * for the numbering system, the instance is initialized with the specified 
numbering
 * system if the JRE implementation supports it. For example,
 * <pre>
 * NumberFormat.getNumberInstance(Locale.forLanguageTag("th-TH-u-nu-thai"))
 * </pre>
 * This may return a {@code NumberFormat} instance with the Thai numbering 
system,
 * instead of the Latin numbering system.
 *
 * @param locale the desired locale
 * @exception NullPointerException if <code>locale</code> is null
 */
public DecimalFormatSymbols( Locale locale ) {
    initialize( locale );
}{code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to