0

I tried to use localization in java to print date with local style. I already make a similar functionality with numbers and currencies but I failed to apply the same behavior to date.

As I learning when I posted this topics few days ago, GraalVM Quarkus Locale in native mode , use localization in native mode need to use create an "@AutomaticFeature".

This trick works for numbers and currencies :

@AutomaticFeature
public class NativeNumberFormatFeature implements Feature {

    @Override
    public void beforeAnalysis(BeforeAnalysisAccess access) {
        ImageSingletons
                .lookup(RuntimeClassInitializationSupport.class)
                .initializeAtBuildTime(NumberFormatSupport.class, this.getClass().getName());

        ImageSingletons.add(NumberFormatSupport.class, new NumberFormatSupport());
    }

}

public class NumberFormatSupport {

    private Map<Locale, NumberFormat> numberInstancesByLocale;
    private Map<Locale, Map<String, NumberFormat>> currencyInstancesByLocale;

    public NumberFormatSupport() {
        numberInstancesByLocale = new HashMap<>();
        currencyInstancesByLocale = new HashMap<>();
        for (Locale locale : Locale.getAvailableLocales()) {
            numberInstancesByLocale.put(locale, NumberFormat.getNumberInstance(locale));
            currencyInstancesByLocale.put(locale, new HashMap<>());
            for (Currency currency : Currency.getAvailableCurrencies()) {
                currencyInstancesByLocale.get(locale).put(currency.getCurrencyCode(), NumberFormat.getCurrencyInstance(locale));
                currencyInstancesByLocale.get(locale).get(currency.getCurrencyCode()).setCurrency(currency);
            }
        }
    }

    public NumberFormat getNumberFormat(Locale locale) {
        return (NumberFormat) numberInstancesByLocale.get(locale).clone();
    }

    public NumberFormat getCurrencyFormat(Locale locale, Currency currency) {
        return (NumberFormat) currencyInstancesByLocale.get(locale).get(currency.getCurrencyCode()).clone();
    }

}

But it's not works with DateTimeFormatter :

@AutomaticFeature
public class NativeDateFormatterFeature implements Feature {

    @Override
    public void beforeAnalysis(BeforeAnalysisAccess access) {
        ImageSingletons
                .lookup(RuntimeClassInitializationSupport.class)
                .initializeAtBuildTime(DateFormatterSupport.class, this.getClass().getName());

        ImageSingletons.add(DateFormatterSupport.class, new DateFormatterSupport());
    }
}

public class DateFormatterSupport {

    private Map<Locale, DateTimeFormatter> dateTimeFormatterByLocale;

    public DateFormatterSupport() {
        dateTimeFormatterByLocale = Arrays.stream(Locale.getAvailableLocales()).collect(Collectors.toMap(
            Function.identity(),
            l -> DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(l)));
    }

    public DateTimeFormatter get(Locale locale) {
        return dateTimeFormatterByLocale.get(locale);
    }

}

In development mode all is ok but in native mode, locale is ignore. Style is always le same, month name isn't translate. I was looking for a solution on google but i didn't find anything so I ask on StackOverflow.

I am at your disposal if needed.

Regards, Stéphane.

4

1 回答 1

0

我不明白为什么,但以下解决方案有效:

public class DateFormatterSupport {

    private Map<Locale, DateTimeFormatter> dateTimeFormatterByLocale;

    public DateFormatterSupport() {
        dateTimeFormatterByLocale = Arrays.stream(Locale.getAvailableLocales()).collect(Collectors.toMap(
            Function.identity(),
            l -> DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(l)));

        Arrays.stream(Locale.getAvailableLocales()).forEach(locale -> {
            dateTimeFormatterByLocale.get(locale).format(LocalDate.now());
        });
    }

    public DateTimeFormatter get(Locale locale) {
        return dateTimeFormatterByLocale.get(locale);
    }

}
于 2020-07-05T19:07:54.920 回答