将Joda LocalTime转换为java.sql.Date

时间:2013-04-24 10:50:16

标签: java date jdbc jodatime

要进行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?

4 个答案:

答案 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()

希望有帮助