什么是 Java8 java.time
等同于
org.joda.time.formatDateTimeFormat.shortDate()
我试过以下方法,但它无法解析诸如“20/5/2016”或“20/5/16”之类的值。
DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
最佳答案
你是对的:Joda-Time DateTimeFormatter
(这是你从 DateTimeFormat.shortDate()
获得的类型)比 java.time 解析更宽松>日期时间格式化程序
。在英语/新西兰语言环境 (en-NZ
) 中,shortDate
使用格式模式 d/MM/yy
并同时解析 20/5/2016
和 20/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
与 d
,MM
与 M
和任意数量的 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]");
- 它涵盖了比您的 Joda-Time 格式化程序更多的案例。也许这样很好。具体来说,您的 Joda-Time 格式化程序坚持在数字之间使用斜杠
/
并拒绝连字符、点或空格。此外,我相信 Joda-Time 会反对将年份完全排除在外。 - 虽然您确实需要
[yyyy][yy]
,但您不需要[d][dd]
也不需要[M][MM]
。只需d
和M
就足够了,因为它们也接受两位数(您的代码中发生的情况是,例如[d]
解析一个或两个数字,因此永远不会使用[dd]
)。 - 如果您只喜欢一种格式模式字符串,我希望
d[/][-][.][ ]M[/][-][.][ ][yyyy][yy]
工作(除了在省略年份的情况下)(我没有测试过)。
关于Java8 相当于 JodaTime DateTimeFormat.shortDate(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58160930/