【问题标题】:Parse date or datetime both as LocalDateTime in Java 8在 Java 8 中将日期或日期时间都解析为 LocalDateTime
【发布时间】:2018-03-16 14:22:54
【问题描述】:

我需要解析一个字段,该字段有时作为日期给出,有时作为日期/时间给出。是否可以使用 Java 8 time API 为此使用单一数据类型? 目前,我尝试使用 LocalDateTime ,但用于以下调用 LocalDateTime.parse("1986-04-08", DateTimeFormatter.ofPattern("yyyy-MM-dd")) 我得到一个

java.time.DateTimeException: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 1986-04-08 of type java.time.format.Parsed

这是一些通用解析器的一部分,它接受日期/日期时间解析模式作为配置选项。所以例如使用硬编码解析模式的以下解决方案

if ("yyyy-MM-dd".equals(pattern)) {
    LocalDate.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd"))).atStartOfDay()
}

不适合我。

欢迎任何其他建议如何以干净的方式对其进行编码。

【问题讨论】:

标签: java java-8 java-time


【解决方案1】:

只需使用构建器 DateTimeFormatterBuilder 创建自定义格式化程序

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendPattern("yyyy-MM-dd[ HH:mm:ss]")
        .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
        .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
        .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
        .toFormatter();

此格式化程序使用[] 括号来允许格式中的可选部分,并添加小时HOUR_OF_DAY、分钟MINUTE_OF_HOUR 和秒SECOND_OF_MINUTE 的默认值。

注意:您可以省略分钟和秒,只需提供小时即可。

照常使用。

LocalDateTime localDateTime1 = LocalDateTime.parse("1994-05-13", formatter);
LocalDateTime localDateTime2 = LocalDateTime.parse("1994-05-13 23:00:00", formatter);

这会输出正确的日期时间,默认小时数为 0(一天的开始)。

System.out.println(localDateTime1); // 1994-05-13T00:00
System.out.println(localDateTime2); // 1994-05-13T23:00

【讨论】:

    【解决方案2】:

    何塞使用parseDefaulting 的回答很好。如果您不想使用DateTimeFormatterBuilder,还有另一种选择。

    首先,您创建带有可选部分的格式化程序 - 在本例中为时间部分,由 [] 分隔:

    DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd[ HH:mm:ss]");
    

    然后调用parseBest,提供要解析的String 和方法引用列表:

    TemporalAccessor parsed = fmt.parseBest("1986-04-08", LocalDateTime::from, LocalDate::from);
    

    在这种情况下,它会首先尝试创建一个LocalDateTime,如果不可能,它会尝试创建一个LocalDate(如果都不可能,它会抛出一个异常)。

    然后,您可以检查返回的类型,并采取相应措施:

    LocalDateTime dt;
    if (parsed instanceof LocalDateTime) {
        // it's a LocalDateTime, just assign it
        dt = (LocalDateTime) parsed;
    } else if (parsed instanceof LocalDate) {
        // it's a LocalDate, set the time to whatever you want
        dt = ((LocalDate) parsed).atTime(LocalTime.MIDNIGHT);
    }
    

    如果结果是LocalDate,您可以按照其他人的建议选择拨打atStartOfDay(),或更改为特定的一天中的时间,例如上午10:30 的atTime(LocalTime.of(10, 30)) .

    【讨论】:

      【解决方案3】:

      我知道答案已经晚了,但它可以帮助其他人......

      由于 LocalDateTime 需要设置时间,否则只能使用 LocalDate,我搜索了 LocalDateTime 内置解决方案来处理这个问题。 我没有找到,但是我使用了以下方法:

      // For specific date (the same as the question)
      LocalDateTime specificDate LocalDateTime.of(LocalDate.of(1986, 4, 8), LocalTime.MIN);
      

      其他示例:

      // For the start of day
      LocalDateTime startToday = LocalDateTime.of(LocalDate.now(), LocalTime.MIN));
      
      // For the end of day
      LocalDateTime endOfToday = LocalDateTime.of(LocalDate.now(), LocalTime.MAX));
      

      这样您就不需要使用格式化程序。 :)

      【讨论】:

        猜你喜欢
        • 2015-12-25
        • 2015-06-26
        • 2016-09-12
        • 2014-01-29
        • 2017-09-26
        • 2020-10-23
        • 1970-01-01
        • 2013-03-27
        • 1970-01-01
        相关资源
        最近更新 更多