简体   繁体   English

Quarkus GraalVM 原生镜像 DateTimeFormatter 和 Localization

[英]Quarkus GraalVM native image DateTimeFormatter and Localization

I tried to use localization in java to print date with local style.我尝试在 java 中使用本地化来打印具有本地风格的日期。 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".正如我几天前发布此主题时了解到的, GraalVM Quarkus Locale in native mode ,在本地模式下使用本地化需要使用创建一个“@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:但它不适用于 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.我在谷歌上寻找解决方案,但我没有找到任何东西,所以我在 StackOverflow 上询问。

I am at your disposal if needed.如果需要,我随时为您服务。

Regards, Stéphane.问候,斯蒂芬。

I don't understand why, but the following solution works:我不明白为什么,但以下解决方案有效:

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);
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM