Java8 相当于 JodaTime DateTimeFormat.shortDate()

Java8 equivalent of JodaTime DateTimeFormat.shortDate()

Java8 java.time 等同于

是什么
org.joda.time.formatDateTimeFormat.shortDate()

我试过以下方法,但它无法解析诸如“20/5/2016”或“20/5/16”之类的值。

DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT) 

FormatStyle.SHORT returns 最短格式 dd/MM/yyd/M/yy 格式,因此您需要使用 pattern 来获取自定义格式

LocalDate date = LocalDate.now();   
System.out.println(date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)));   //9/29/19

您也可以使用DateTimeFormatter.ISO_DATEDateTimeFormatter.ISO_LOCAL_DATE获取iso格式,如yyyy-MM-dd,您也可以在DateTimeFormatter

中查看可用格式]
System.out.println(date.format(DateTimeFormatter.ISO_DATE));       //2019-09-29
System.out.println(date.format(DateTimeFormatter.ISO_LOCAL_DATE)); //2019-09-29

如果您想要像 yyyy/MM/dd 这样的自定义格式,请使用 ofPattern

System.out.println(date.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"))); //2019/09/29

你是对的:Joda-Time DateTimeFormatter(这是你从 DateTimeFormat.shortDate() 得到的类型)比 java.time DateTimeFormatter 解析更宽松。在 English/New Zealand locale (en-NZ) shortDate 使用格式模式 d/MM/yy 并将 20/5/201620/5/16 解析为 2016-05-20 .

坦率地说,我觉得它把两位数和四位数的年份都解释为同一年很讨厌。当格式指定两位数年份时,我希望四位数字是更严格的输入验证的错误。当格式指定两位数时接受一位数月份也很宽松,但可能不那么危险并且更符合我们的预期。

java.time 也使用格式模式 d/MM/yy(在 jdk-11.0.3 上测试)。解析时接受一位或两位数字表示月份,但坚持两位数月份和两位数年份。

您可能会在 java.time 中获得 Joda-Time 行为,但它需要您自己指定格式模式:

    Locale loc = Locale.forLanguageTag("en-NZ");
    DateTimeFormatter dateFormatter
            = DateTimeFormatter.ofPattern("d/M/[yyyy][yy]", loc);

    System.out.println(LocalDate.parse("20/5/2016", dateFormatter));
    System.out.println(LocalDate.parse("20/5/16", dateFormatter));

输出为:

2016-05-20
2016-05-20

如果您想要一个适用于其他语言环境的高级解决方案,我相信您可以编写一段代码,从 DateTimeFormatterBuilder.getLocalizedDateTimePattern 获取格式模式并通过将 dd 替换为dMMM 以及任意数量的 y[yyyy][yy]。然后将修改后的格式模式字符串传给DateTimeFormatter.ofPattern.

编辑:很高兴您有工作要做。在您的评论中,您说您使用了:

    Stream<String> shortFormPatterns = Stream.of(
            "[d][dd]/[M][MM]",
            "[d][dd]-[M][MM]",
            "[d][dd].[M][MM]",
            "[d][dd] [M][MM]",
            "[d][dd]/[M][MM]/[yyyy][yy]",
            "[d][dd]-[M][MM]-[yyyy][yy]",
            "[d][dd].[M][MM].[yyyy][yy]",
            "[d][dd] [M][MM] [yyyy][yy]");
  1. 它涵盖了比您的 Joda-Time 格式化程序更多的案例。也许这样很好。具体来说,您的 Joda-Time 格式化程序坚持在数字之间使用斜杠 /,并拒绝连字符、点或 space。我也相信 Joda-Time 会反对完全忽略年份。
  2. 虽然您确实需要 [yyyy][yy],但您不需要 [d][dd] 也不需要 [M][MM]。只需 dM 就足够了,因为它们也接受两位数字(您的代码中发生的情况是,例如 [d] 解析一位或两位数字,因此从不使用 [dd]无论如何)。
  3. 如果你只喜欢一种格式模式字符串,我希望 d[/][-][.][ ]M[/][-][.][ ][yyyy][yy] 可以工作(除了在省略年份的情况下)(我没有测试过)。