我只是想在Java 8中将日期字符串转换为DateTime对象。运行以下几行代码:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime dt = LocalDateTime.parse("20140218", formatter);
我得到以下错误:
Exception in thread "main" java.time.format.DateTimeParseException:
Text '20140218' could not be parsed:
Unable to obtain LocalDateTime from TemporalAccessor:
{},ISO resolved to 2014-02-18 of type java.time.format.Parsed
at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1918)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1853)
at java.time.LocalDateTime.parse(LocalDateTime.java:492)
语法与这里建议的完全相同,但是我遇到了一个异常。我使用的是JDK-8u25。
对于值得的是,如果有人应该再次阅读这个主题(像我一样),正确的答案将在DateTimeFormatter定义中,例如:
private static DateTimeFormatter DATE_FORMAT =
new DateTimeFormatterBuilder().appendPattern("dd/MM/yyyy[ [HH][:mm][:ss][.SSS]]")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter();
如果将出现可选字段,则应该设置可选字段。其余的代码应该完全相同。
编辑:有用的东西从wittyameta评论:
记住在调用appendPattern之后添加parsedefaults。否则它会给出DateTimeParseException
扩展retrography的答案..:我有同样的问题,即使使用LocalDate而不是LocalDateTime。问题是,我已经创建了我的DateTimeFormatter使用. withresolverstyle (ResolverStyle.STRICT);,所以我必须使用日期模式uuuuMMdd而不是yyyyMMdd(即。“year”而不是“year-of-era”)!
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseStrict()
.appendPattern("uuuuMMdd")
.toFormatter()
.withResolverStyle(ResolverStyle.STRICT);
LocalDate dt = LocalDate.parse("20140218", formatter);
(这个解决方案最初是对retrography的答案的评论,但我被鼓励将其作为一个独立的答案发布,因为它显然对许多人都很有效。)
如果日期字符串不包括任何小时、分钟等值,则不能直接将其转换为LocalDateTime。您只能将其转换为LocalDate,因为字符串只表示年、月和日期组件,这将是正确的做法。
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate ld = LocalDate.parse("20180306", dtf); // 2018-03-06
无论如何,你可以将它转换为LocalDateTime。
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate ld = LocalDate.parse("20180306", dtf);
LocalDateTime ldt = LocalDateTime.of(ld, LocalTime.of(0,0)); // 2018-03-06T00:00
对于那些像我一样犯了这个错误的人:
无法从TemporalAccessor获取LocalDateTime: {HourOfAmPm=0, MinuteOfHour=0}
它来自于下面这句话:
LocalDateTime.parse(date, DateTimeFormatter.ofPattern("M/d/yy h:mm"));
事实证明,这是因为我在0小时上使用了12小时的模式,而不是24小时的模式。
通过使用大写H将小时改为24小时模式可以修复它:
LocalDateTime.parse(date, DateTimeFormatter.ofPattern("M/d/yy H:mm"));
如果您只是想采用一种格式(无论它是否有时间),并希望解析为LocalDateTime,您可以执行以下操作。
LocalDateTime parseDateTime(String dateTime, DateTimeFormatter fmt) {
return fmt.parse(dateTime, t -> {
LocalDate date = t.query(TemporalQueries.localDate());
LocalTime time = t.query(TemporalQueries.localTime());
return LocalDateTime.of(date, time != null ? time : LocalTime.MIDNIGHT);
});
}
我需要这个,因为我要将日期/时间模式作为自定义Spark UDF的参数。
您不需要定义DateTimeFormatter
您不需要定义DateTimeFormatter来解析给定的日期字符串。您可以使用OOTB(开箱即用)、DateTimeFormatter。BASIC_ISO_DATE解析它。
演示:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
LocalDate date = LocalDate.parse("20140218", DateTimeFormatter.BASIC_ISO_DATE);
System.out.println(date);
// In case you need an instance of LocalDateTime
LocalDateTime ldt = date.atTime(LocalTime.MIN);
System.out.println(ldt);
}
}
输出:
2014-02-18
2014-02-18T00:00
在线演示
了解更多关于现代日期时间API*从Trail: Date Time。
*如果你正在为一个Android项目工作,而你的Android API级别仍然不兼容Java-8,检查Java 8+ API通过desugaring可用。注意,Android 8.0 Oreo已经提供了对java.time的支持。检查这个答案和这个答案,学习如何使用java。使用JDBC的时间API。