SimpleDateFormat toPattern在java 9中的行为有所不同

时间:2018-02-16 15:07:29

标签: java date simpledateformat date-format java-9

DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, new Locale("SV", "SE"));
((SimpleDateFormat) dateFormat).toPattern();

在Java 8中,这一行产生"yyyy-MM-dd",而在Java 9中,它产生"y-MM-dd"

这对我们的遗留代码有一些严重问题,是否有某种方法可以恢复行为?

1 个答案:

答案 0 :(得分:5)

    System.setProperty("java.locale.providers", "COMPAT,CLDR");
    DateFormat dateFormat
            = DateFormat.getDateInstance(DateFormat.SHORT, new Locale("sv", "SE"));
    System.out.println(((SimpleDateFormat) dateFormat).toPattern());

在我的jdk-9.0.4上运行,打印

  

YYYY-MM-DD

您可能希望在命令行中使用-D设置属性,它应该没有任何区别。

在Java 9中,Unicode Consortium中的公共区域设置数据存储库(CLDR)用作区域设置数据的默认源,而早期Java版本则不是这种情况。如上所述设置系统属性可启用Java 8行为。正如nullpointer在评论中所说,你可以阅读更多here: Use CLDR Locale Data by Default

Basil Bourque在他的评论中是正确的,习惯上使用小写缩写语言,因此您应该指定sv以确保不会混淆您的读者。

人们可能也想知道模式中是否有一个y或四个是否有任何区别。我阅读SimpleDateFormat文档的方式,一个y将根据80-20规则解释一个2位数的年份:它在过去80年内或在接下来的20年内。yyyy将公元一世纪的两位数年份解释为一年。假设你的年份在4位数范围内(1000到9999),我不认为这是一个问题。

如果这仅适用于瑞典语语言环境,则现代版本的代码会产生相同的结果:

DateTimeFormatterBuilder.getLocalizedDateTimePattern(
        FormatStyle.SHORT, null, IsoChronology.INSTANCE, new Locale("SV", "SE")));

但是,对于多个区域设置(例如en-CY,塞浦路斯英语),结果与DateFormatDateTimeFormatter不同,因此如果您的目标是最大向后兼容性,请坚持使用过时的DateFormat课程。