在Java 8中如何将LocalDateTime转换为java.sql.Date?

28
如何将 LocalDateTime 转换为 java.sql.Date 中?
我在互联网上的搜索结果大多是与Timestamp相关的代码或者是将LocalDate转换成java.sql.Date。我正在寻找将LocalDateTime转换为java.sql.Date的方法。

我认为有一个误解,如果你在LocalDateTime中有日期和时间,自然的转换是到java.sql.Timestamp,因为假定你的列有这些信息或将会有。而如果你只有LocalDate中的日期,则转换将是到java.sql.Date。当然这只是我的个人意见。你可以在这里了解更多:https://dev59.com/R2w15IYBdhLWcg3wLIzI - pazfernando
4个回答

35

LocalDateTimejava.sql.Date之间没有直接的关联,因为前者是时间戳,而后者是日期。

然而,LocalDatejava.sql.Date之间存在关联,可以通过以下方式进行转换:

LocalDate date = //your local date
java.sql.Date sqlDate = java.sql.Date.valueOf(date)

对于任何给定的LocalDateTime,它会为您提供以下代码:

LocalDateTime dateTime = // your ldt
java.sql.Date sqlDate = java.sql.Date.valueOf(dateTime.toLocalDate());

19
java.Sql.Date会保留时间组件。这个解决方案会导致时间部分丢失。 - Andy Thomas
4
这个问题是关于将 DateTime 转换为 sql.Date 的,显然它不关心保留时间。如果我们关心时间,我们会转换为 sql.Timestamp。@AndyThomas - M. Prokhorov
1
https://docs.oracle.com/javase/6/docs/api/java/sql/Date.html - 这个类支持时间组件(虽然已经被弃用),因此显然它可以/会关心保留时间。 - Andy Thomas
1
一旦您在sql.Date对象上调用getHours方法,您可能会重新考虑它是否具有时间。那里没有任何时间组件。 它从java.util.Date继承的事实是JDK开发人员非常不幸的错误。 - M. Prokhorov

31

@M. Prokhorov的回答是正确的,我只想补充一些点。

java.sql.Date仅保留日、月和年份。时间值(小时、分钟、秒和毫秒)全部设置为零。因此,当将LocalDateTime转换为java.sql.Date时,这些字段会丢失。

如果您正在进行单向转换,而且不介意丢失这些字段,则可以这样做:

LocalDateTime dt = // LocalDateTime value
// convert to Date (time information is lost)
java.sql.Date date = java.sql.Date.valueOf(dt.toLocalDate());

但是如果你想要稍后恢复原始的 LocalDateTime,最好分别保存时间字段,这样你就可以恢复它:

LocalDateTime dt = // your LocalDateTime
// save time information (hour, minute, seconds, fraction of seconds)
LocalTime savedTime = dt.toLocalTime();
// convert to Date (time information is lost)
java.sql.Date date = java.sql.Date.valueOf(dt.toLocalDate());

// retrieve back the LocalDate (only day/month/year)
LocalDate localDate = date.toLocalDate();
// retrieve the LocalDateTime, with the original time values
LocalDateTime ldt = localDate.atTime(savedTime);

1
这个答案必须是这个问题的正确答案加1。 - cihan adil seven
java.sql.Date中的时间值不会被设置为零 - 实际上根本没有这样的值。在OpenJDK中,对java.sql.Date调用getHours()setSeconds(v)将导致IllegalArgumentException,甚至调用toInstant()也会导致UnsupportedOperationException。只有在调用getTime()时,这些值才会显示为零。 - M. Prokhorov

3

可以通过使用java.util.Date作为中间层,在不需要对时区进行假设的情况下将LocalDateTime转换为java.sql.date,同时保留时间部分:

LocalDateTime dateValue = // your LocalDateTime
java.util.Date utilDate;
String dateFormat = "yyyy-MM-dd'T'HH:mm:ss";
DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern(dateFormat);
SimpleDateFormat sdf1 = new SimpleDateFormat(dateFormat);
try {
    utilDate = sdf1.parse(dateValue.format(dtf1));
} catch (ParseException e) {
    utilDate = null; // handle the exception
}
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());

它不保留时间部分。 - undefined

0

你可以从带有时间的LocalDateTime对象中获取java.sql.Date对象,但这并不是很优雅。

new Date(Timestamp.valueOf(LocalDateTime.now()).getTime())

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接