如何更改JDK8中的DateFormatSymbols以解决与JDK7(属性月份名称)的不兼容问题?

时间:2015-05-17 11:46:09

标签: java-8 datetime-format incompatibility

正如Xaerxess在本主题中所发现的那样:Month name in genitive (Polish locale) with Joda-Time DateTimeFormatter 在JDK8中,DateFormatSymbols.getInstance(新的Locale(" pl"," PL"))。getMonths()默认返回genitive中的月份名称。以前的Java版本在主格情况下返回月份名称。 有了这个,例如,SimpleDateFormat格式与" dd-MMMM-yyyy"在JDK8中,模式给出的结果与JDK6或7中的结果不同。

这是一个很大的变化,我的一些旧应用程序无法正常使用新的月份名称。我正在寻找一种解决方案来更改Locale PL的全局默认月份名称。

我尝试使用DateFormatSymbols.getInstance()。setMonths(new String [] {..}),但它不能全局工作。

如果我找到使用Java代码更改默认月份名称的解决方案,我可以在应用程序初始化时添加此代码,而无需更正整个应用程序。在我的情况下,我只需使用load-on-startup选项将servlet添加到我的Web应用程序中。

或者你可能有不同的想法如何在这种情况下兼容Java 8?也许有一些参数/选项可以在开始时传递给jvm?

1 个答案:

答案 0 :(得分:1)

我有同样的问题。在所有十亿标准中,我的客户决定在本月使用所有大写字母来打破默认解析器。所以我的日期看起来像:

02-DEC-15

现在Java时间可以解析“Dec”而不是“DEC”。烦人..我搜索了一会儿,发现java8替代了这个问题。

这是您可以向格式化程序添加自定义内容的方法:

public static void main(String[] args) {
    String test = "02-DEC-15";

    Map<Long, String> lookup = new HashMap<>();
    lookup.put(1L, "JAN");
    lookup.put(2L, "FEB");
    lookup.put(3L, "MAR");
    lookup.put(4L, "APR");
    lookup.put(5L, "MAY");
    lookup.put(6L, "JUN");
    lookup.put(7L, "JUL");
    lookup.put(8L, "AUF");
    lookup.put(9L, "SEP");
    lookup.put(10L, "OCT");
    lookup.put(11L, "NOV");
    lookup.put(12L, "DEC");

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                                      .appendPattern("dd-")
                                      .appendText(ChronoField.MONTH_OF_YEAR, lookup)
                                      .appendPattern("-yy")
                                      .toFormatter();

    LocalDate parse = LocalDate.parse(test,formatter);
    System.out.println(parse);
}

这有点棘手,因为它没有按照我的预期行事。这里有几点需要考虑:

每个追加调用都会添加一个新的解析器实例,如果它不起作用,将被称为 IN ORDER 严格失败。例如,如果您采用上面的示例并认为您可以添加几个月,请说:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                                  .appendPattern("dd-MMM-yy")
                                  .appendText(ChronoField.MONTH_OF_YEAR, lookup)
                                  .toFormatter();

这将失败,因为该模式为您的格式化程序添加了多个解析器:

dd
-
MMM
-
yy

在最后添加查找将不起作用,因为MMM已经失败了您的解析上下文。

因此可以单独添加每个步骤。看看:

MonthDay#PARSER

这最终帮助我找到了正确的解决方案。无论如何,使用Builder你可以构建你想要的任何怪异的非标准解析器。但是请记得对那些认为他们能想出另一种表达需要释放到这个世界的日期的方式的人大喊大叫。

我希望这可以为某些人带来一些心痛。

阿图尔

编辑:所以我再一次忽略了这个问题。除非您自己注册提供商,否则我认为没有默认方式。然而,这对我来说似乎有点不对劲。我认为解析的工作方式是使用您使用的解析器的静态实例。这是关于如何实现例如java时间中的默认解析器的实现。 因此,只需在启动时创建自定义解析器,并在整个应用程序中引用它进行解析。