要进行JDBC查询,我需要将日期传递给它。日期保存在Date
field类型的PostgreSql数据库中,该数据库代表特定日期,没有任何时间。
因为我只需要约会,所以我决定使用仅代表没有时间的日期的特定对象,即LocalDate
from Joda-Time package。我认为这很重要,因为如果我使用DateTime对象,它将携带冗余时间数据,并且当时钟向后放置一小时时可能导致夏令时结束时的错误(尽管情况空前罕见,但不是不可能的)。
但是当我开始尝试使用LocalDate
方法的可接受参数对preparedStatement.setDate
对象进行平方时,我找不到合适的方法。
setDate
接受java.sql.Date
作为参数。构造java.sql.Date
对象的唯一选择是以毫秒为单位传递时间。
但这违背了使用Joda-Time软件包中的LocalDate
的所有目的,因为在此转换时我们会回到毫秒,并且在这些转换发生时,时钟可能会被放回一小时并将日期更改为上一个日期。
所以,现在我的代码中有这一行:
preparedStatement.setDate(1, new java.sql.Date(localDate.toDate().getTime()));
但这是将LocalDate
转换为setDate
格式接受的最佳方法吗?
我的担忧是否与夏令时和相应的时钟转换有关?
有没有更好的方法将日期(并且只有没有时间的日期)传递给JDBC preparedStatement?
答案 0 :(得分:10)
使用您的技术应该是安全的,因为LocalDate#toDate
会考虑所有时区问题。您所拥有的毫秒级瞬间与上下文无关:它与您用于转换的语言环境中该时间点有效的时区唯一关联。换句话说,如果你在一年内重复完全相同的毫秒值转换,你将始终得到完全相同的答案,即使时区法规因此而改变,因为JDK引用到一个数据库,记录世界各地所有时区变化的完整历史。
在推理这些问题时,请务必记住,您当前的时区对转化没有任何影响,转化由区域设置参数化,并仅在转换瞬间的上下文中解析时区
我全心全意地同情你对这一切的不满:它正在将一个简单而直接的操作变成一个复杂的计算迷宫,除了招惹麻烦之外什么都不做。希望Java 8及其新的(是的,再次!)日期/时间API在JodaTime的基础上取得积极的转变。
答案 1 :(得分:4)
我今天遇到了同样的问题。我使用的是JDK 8.经过几个小时的搜索,我终于找到了Java SE 8 Documentation的答案。这是解决方案:
statement.setDate(5, java.sql.Date.valueOf(personToUpdate.getBirthday()));
语句是PreparedStatement实例。 " personToUpdate.getBirthday()"是LocalDate的类型。
答案 2 :(得分:1)
由于org.joda.time.toDateMidnight()和org.joda.time.toDateMidnight(DateTimeZone区域)已被弃用,因此这个解决方案非常适合我。
我的典型课程,要坚持:
...
import org.joda.time.LocalDate;
...
public class MyObject implements Serializable {
...
private LocalDate startDate;
...
private EndDate startDate;
// Getters and Setters
...
...
}
我是其他课程,我坚持startDate,我有:
myObject.setStartDate(new LocalDate(myObject.getStartDate().toDateTimeAtStartOfDay(DateTimeZone.getDefault())));
答案 3 :(得分:0)
尝试使用LocalDate#toDateMidnight()
将时间设置为0,然后设置DateMidnight#toDate()
。
Date date = localDate.toDateMidnight().toDate();
或者,如果您使用的是JodaTime 1.5或更高版本,请使用LocalDate#toDateTimeAtStartOfDay()
,然后使用DateTime#toDate()
希望有帮助