【问题标题】:Java 8 DateTimeFormatter with optional part带有可选部分的 Java 8 DateTimeFormatter
【发布时间】:2018-01-16 11:42:12
【问题描述】:

我有一个代表日期(有或没有时间)的字符串,例如 13/12/201713/12/2017 15:39:51

所以我正在尝试使用带有可选部分的 java 8 DateTimeFormatter。

该代码有效

LocalDateTime localDateTime = LocalDateTime.parse("13/12/2017 15:39:51",DateTimeFormatter.ofPattern("dd/MM/yyyy[ HH:mm:ss]"));
System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")));
System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("HH:mm:ss")));

13/12/2017
15:39:51

但我不明白为什么那个没有

LocalDateTime localDateTime = LocalDateTime.parse("13/12/2017",DateTimeFormatter.ofPattern("dd/MM/yyyy[ HH:mm:ss]"));

给我

Exception in thread "main" java.time.format.DateTimeParseException: Text '13/12/2017' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2017-12-13 of type java.time.format.Parsed
at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855)
at java.time.LocalDateTime.parse(LocalDateTime.java:492)
...

即使有

LocalDateTime localDateTime = LocalDateTime.parse("13/12/2017",DateTimeFormatter.ofPattern("dd/MM/yyyy"));

它不适用于相同的异常。

【问题讨论】:

    标签: time java-8


    【解决方案1】:

    使用parseBest

    当您使用可选组件时,您应该使用parseBest 进行解析。您的应用程序可能仅使用 parse 工作,但这只是靠运气(因为您只解析完整输入,而不是部分输入)。使用parseBest,您可以正确处理各种TemporalAccessor,这就是使用 optional 的全部原因。

    返回TemporalAccessor 的决定相当简单:parseBest 将尝试按参数顺序匹配每个TemporalQuery。当任何匹配时,该方法返回那个。因此,请确保从最精确到不太精确。此外,如果没有匹配到,则会抛出异常。

    LocalDateTime dateTime;
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy[ HH:mm:ss]");
    TemporalAccessor temporalAccessor = formatter.parseBest("13/12/2017", LocalDateTime::from, LocalDate::from);
    if (temporalAccessor instanceof LocalDateTime) {
      dateTime = (LocalDateTime)temporalAccessor;
    } else {
      dateTime = ((LocalDate)temporalAccessor).atStartOfDay();
    }
    

    【讨论】:

    • 我使用该解决方案有一段时间了,但我注意到了一个小问题。如果输入日期秒数是 00 (17/01/2018 08:30:00),它给我的是 2018-01-17T08:30 而不是 2018-01-17T08:30:00。有解决办法吗?
    • @tweetysat 您在上面所说的是格式问题,而不是解析问题。要修复它,请检查this answer
    • 感谢@Olivier Grégoire。我修好了。
    猜你喜欢
    • 2018-12-06
    • 2018-12-13
    • 1970-01-01
    • 1970-01-01
    • 2015-07-17
    • 1970-01-01
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多