将日期或日期时间都解析为 Java 中的 LocalDateTime 8
Parse date or datetime both as LocalDateTime in Java 8
我需要解析一个字段,该字段有时以日期形式给出,有时以 date/time 形式给出。是否可以使用 Java 8 次 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
这是一些接受 date/datetime 解析模式作为配置选项的通用解析器的一部分。所以例如下面是硬编码解析模式的解决方案
if ("yyyy-MM-dd".equals(pattern)) {
LocalDate.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd"))).atStartOfDay()
}
我不适合。
欢迎提出如何以简洁的方式编写代码的任何其他建议。
只需使用构建器创建自定义格式化程序 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
Jose 使用 parseDefaulting
的回答很好。如果您不想使用 DateTimeFormatterBuilder
.
,还有另一种选择
首先,您使用可选部分创建格式化程序 - 在本例中为 time-of-day 部分,由 []
:
分隔
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
(如果 none 可能,它会抛出异常)。
然后,您可以检查返回的是哪种类型,并据此采取行动:
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()
,如其他人所建议的,或者更改为特定的time-of-day,例如atTime(LocalTime.of(10, 30))
例如 10:30 AM。
我知道回答晚了,但它可以帮助其他人...
由于 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));
这样你就不需要使用格式化程序了。 :)
我需要解析一个字段,该字段有时以日期形式给出,有时以 date/time 形式给出。是否可以使用 Java 8 次 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
这是一些接受 date/datetime 解析模式作为配置选项的通用解析器的一部分。所以例如下面是硬编码解析模式的解决方案
if ("yyyy-MM-dd".equals(pattern)) {
LocalDate.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd"))).atStartOfDay()
}
我不适合。
欢迎提出如何以简洁的方式编写代码的任何其他建议。
只需使用构建器创建自定义格式化程序 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
Jose 使用 parseDefaulting
的回答很好。如果您不想使用 DateTimeFormatterBuilder
.
首先,您使用可选部分创建格式化程序 - 在本例中为 time-of-day 部分,由 []
:
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
(如果 none 可能,它会抛出异常)。
然后,您可以检查返回的是哪种类型,并据此采取行动:
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()
,如其他人所建议的,或者更改为特定的time-of-day,例如atTime(LocalTime.of(10, 30))
例如 10:30 AM。
我知道回答晚了,但它可以帮助其他人...
由于 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));
这样你就不需要使用格式化程序了。 :)