有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java DateTimeFormatter不能在en语言环境中使用LLLL模式

使用ru语言环境返回完整的月份名称(Февраль),但仅使用en数字(2

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("LLLL", new Locale("ru"));
LocalDate.now().format(formatter);

MMMM使用en,但不使用ru(需要主格)

如何获取所有地区的完整月份名称


共 (2) 个答案

  1. # 1 楼答案

    不幸的是,Java-8尚未解决the related bug issue JDK-8114833。我还不清楚Java-9是否提供了一个解决方案(在那里,功能冻结的日期已经过去)。因此,您可以根据自己的知识应用以下变通方法,哪些语言需要一个特殊的独立表格(提名表格)几个月,哪些不需要:

    private static final Set<String> LANGUAGES_WITH_STANDALONE_CASE;
    
    static {
        Set<String> set = new HashSet<>();
        set.add("ru");
    
        // add more languages which require LLLL-pattern (for example other slavish languages)
        LANGUAGES_WITH_STANDALONE_CASE = Collections.unmodifiableSet(set);
    }
    
    public static void main(String[] args) throws Exception {
    
        Locale locale = new Locale("en");
    
        DateTimeFormatter formatter =
          DateTimeFormatter.ofPattern(
            LANGUAGES_WITH_STANDALONE_CASE.contains(locale.getLanguage()) 
              ? "LLLL" : "MMMM",
            locale
          );
        System.out.println(LocalDate.now().format(formatter));
    
        // ru => Февраль
        // en => February
    }
    

    我不能说我喜欢这个解决方案,因为它需要额外的知识,哪种语言需要哪种模式。但实际上,这是在JSR-310(又名java.time-API)范围内解决问题的唯一可能性

    通过测试,我现在看到,即使是旧类SimpleDateFormat(Java-8版本)也可以工作:

        Locale locale = new Locale("en");
    
        SimpleDateFormat sdf = new SimpleDateFormat("LLLL", locale);
        System.out.println(sdf.format(new Date()));
    

    但是,这种解决方法有一个很大的缺点,就是不能使用普通的日历日期,而只能使用java.util.Date

    或者,您可能愿意为一个库添加一个额外的依赖项,该库更好地支持模式字母“L”,并且具有更好的API样式和更好的性能特征。例如,您可以使用我的库Time4J。下面是后一种情况的演示,它还展示了Time4J的独立格式引擎如何用于JSR-310-types(也用于解析):

        Locale locale = new Locale("ru");
    
        ChronoFormatter<LocalDate> formatter =
            ChronoFormatter.ofPattern(
                "LLLL",
                PatternType.CLDR,
                locale,
                PlainDate.axis(TemporalType.LOCAL_DATE)
            );
        System.out.println(formatter.format(LocalDate.now()));
    
        // ru => Февраль
        // en => February
    

    为了获得最佳性能,我建议将格式化程序惰性地存储在每个区域设置的ConcurrentHashMap

  2. # 2 楼答案

    对于主格,您必须将模式设置为MMLL,而不是MMMM/LLLL

    System.out.println(LocalDate.now().format(DateTimeFormatter.ofPattern("MM", new Locale("ru"))));
    System.out.println(LocalDate.now().format(DateTimeFormatter.ofPattern("MM", new Locale("en"))));
    

    这将为两个地区打印02