【问题标题】:DateTimeFormatter auto-corrects invalid (syntactically possible) calendar dateDateTimeFormatter 自动更正无效(语法上可能)的日历日期
【发布时间】:2015-05-18 16:12:21
【问题描述】:

当您尝试超出可能范围的日期时,Java DateTimeFormatter 会引发异常,例如:

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/yyyy");
String dateString = "12/32/2015";
LocalDate ld = LocalDate.parse(dateString, dtf);

将抛出:

Exception in thread "main" java.time.format.DateTimeParseException: Text '12/32/2015' could not be parsed: Invalid value for DayOfMonth (valid values 1 - 28/31): 32

但是当我输入一个无效的日历日期时,根据他们的标准,它在语法上仍然是可能的,它会自动将其更正为有效日期,例如:

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/yyyy");
String dateString = "2/31/2015";
LocalDate ld = LocalDate.parse(dateString, dtf);

它成功解析但自动更正为2015-02-28。我不希望这种行为,我希望它在日期不是有效的日历日期时仍然抛出异常。有没有我可以设置的内置选项来实现这一点,还是我真的必须尝试手动筛选出这些实例?

【问题讨论】:

    标签: java parsing date formatting java-time


    【解决方案1】:

    您可以使用STRICT 解析器样式:

    import static java.time.format.ResolverStyle.STRICT;
    
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/uuuu").withResolverStyle(STRICT);
    

    默认情况下,ofPattern 使用 a SMART resolver style,这将使用合理的默认值。

    请注意,我使用了uuuu 而不是yyyy,即YEAR 而不是YEAR_OF_ERA。假设您使用的是公历系统,则两者在当前时代(第 1 年或更大)中的年数相等。上面的链接中更详细地解释了差异。

    【讨论】:

    • 这给了我一个不同的例外:Text '2/28/2015' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {DayOfMonth=28, YearOfEra=2015, MonthOfYear=2},ISO of type java.time.format.Parsed
    • 该消息告诉您该时代已丢失 - 在严格模式下,它不再默认。您需要使用DateTimeFormatterBuilderparseDefaulting(ChronoField.ERA, IsoEra.CE.getValue()) docs.oracle.com/javase/8/docs/api/java/time/format/…
    • 在这种情况下我们不能简单地将yyyy 替换为uuuu 吗?
    • @assylias 将其更改为 uuuu 成功了!这有什么意义,为什么会起作用?如果上面的答案因解释而改变,我会将其标记为已回答。
    • @aconkey 补充说明
    猜你喜欢
    • 2018-12-22
    • 1970-01-01
    • 2014-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-24
    相关资源
    最近更新 更多