在Java中检查有效日期。

6

我尝试使用 dd/MM/yyyy 格式来检查一个有效的日期字符串输入,代码如下:

String input = Scanner.nextLine();
DateTimeFormatter formater = DateTimeFormatter.ofPattern("dd/MM/yyyy");
try{
    LocaleDate.parse(input, formater);
}
catch(Exception e)

但它无法检查以下一些规则:

Leap year, February 29 days.

Common year, February 28 days.

Month 1, 3, 5, 7, 8, 10, 12, max 31 days.

Month 4, 6, 9, 11, max 30 days.

当我使用input = "30/02/2022"时,它是合法的。 我使用的是netbeans 8.2jdk 1.8。它们是否支持用于检查这些规则的某些方法?

2个回答

11

你需要在你的格式化程序中更改两件事情:

  • 使用uuuu代替yyyy。尝试后者很容易,但是y表示“纪元内的年份”。 它不知道是公元前还是公元后。 u表示包括纪元信息的“年”。
  • 默认的解析器样式SMART。使用.withResolverStyle(ResolverStyle.STRICT)返回格式化程序的strict副本。

4
不仅如此,“显然”一词,文档明确说明:“它使用SMART解析风格。” - user16320675
是的,我看到了,只是我自己还不知道那件事。 - Rob Spoor
总结一下:这里的 uuuu 用于检查 ERA,因此它有助于检查年份是否为闰年。而 .withResolverStyle(ResolverStyle.STRICT) 用于检查“1月、3月、5月、7月、8月、10月和12月最多31天,4月、6月、9月和11月最多30天”的情况。而 SMART 只是检查月份是否在1到12之间,日期是否在1到31之间。我说得对吗? - hoàng nguyễn

2
您需要启用DateTimeFormatter的严格模式:
DateTimeFormatter formater = DateTimeFormatter.ofPattern("dd/MM/yyyy")
                            .withResolverStyle(ResolverStyle.STRICT);

LocaleDate.parse("30/02/2022, formater);会抛出异常。

(意思是日期格式不正确,应该改为"02/30/2022")

就像我下面所说的那样,你需要使用uuuu代替yyyy,否则会得到其他异常。 - Rob Spoor
严格来说是正确的想法,但这还不够。它会抛出 java.time.format.DateTimeParseException: Text '30/02/2022' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {DayOfMonth=30, MonthOfYear=2, YearOfEra=2022},ISO of type java.time.format.Parsed 异常。但如果我使用 28/02/2022,它会抛出一个非常类似的异常,因此我们不能仅凭它来区分有效和无效日期。 - Ole V.V.
@OleV.V. 这就是 uuuu 的修复作用。它使用的是 Year 字段而不是 YearOfEra,因此 2022 年是公元 2022 年,而不是 2022 年(不知道是公元前还是公元后)。 - Rob Spoor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接