24

要进行 JDBC 查询,我需要将日期传递给它。日期保存在PostgreSql 数据库的Date字段类型中,表示特定的日期,没有任何时间。

因为我只需要日期,所以我决定使用仅代表没有时间的日期的特定对象,它LocalDate来自 Joda-Time 包。我认为这很重要,因为如果我使用 DateTime 对象,它将携带冗余时间数据,并且当时钟向后一小时时,它可能会导致夏令时结束时出现错误(尽管这种情况史无前例,但并非如此不可能的)。

但是当我开始尝试LocalDate用可接受的preparedStatement.setDate方法参数来平方对象时,我没有找到合适的方法来做到这一点。

setDate接受java.sql.Date作为参数。构造对象的唯一选择java.sql.Date是以毫秒为单位传递时间。

但这违背了使用LocalDateJoda-Time 包的所有目的,因为在此转换中我们回到毫秒,当这些转换发生时,时钟可能会延迟一小时并将日期更改为前一个日期。

所以,现在我的代码中有这一行:

preparedStatement.setDate(1, new java.sql.Date(localDate.toDate().getTime()));

但这是转换LocalDate为接受setDate格式的最佳方式吗?

我对夏令时和相应的时钟变化的担忧是否合理?

有没有更好的方法将日期(并且只有没有时间的日期)传递给 JDBCpreparedStatement?

4

5 回答 5

12

使用您的技术应该是安全的,因为所有时区问题都会被LocalDate#toDate. 您所拥有的毫秒瞬间与上下文无关:它与您用于转换的区域设置内的该时间点有效的时区唯一相关。换句话说,如果您在一年中重复转换完全相同的毫秒值,您将始终得到完全相同的答案,即使同时您所在位置的时区规定发生变化,因为 JDK 指的是记录完整历史的数据库世界各地的所有时区变化。

在对这些问题进行推理时,重要的是要记住您当前的时区对转换没有影响,这是由您的语言环境参数化的,并且仅在被转换的瞬间的上下文中解析时区。

我衷心同情你对这一切的不安:它把一个简单而直接的操作变成了一个复杂的计算迷宫,只会招来麻烦。希望 Java 8 及其新的(是的,再次!)日期/时间 API 会发生积极的转变,它坚定地基于 JodaTime。

于 2013-04-24T12:46:34.907 回答
4

我今天遇到了同样的问题。我正在使用 JDK 8。经过几个小时的搜索后,我终于在 Java SE 8 文档中找到了答案。这是解决方案:

statement.setDate(5, java.sql.Date.valueOf(personToUpdate.getBirthday()));

语句是 PreparedStatement 实例。“personToUpdate.getBirthday()”是 LocalDate 的类型。

于 2014-09-19T13:52:04.100 回答
1

由于 org.joda.time.toDateMidnight() 和 org.joda.time.toDateMidnight(DateTimeZone zone) 已被弃用,这对我来说是完美的解决方案。

我的典型课程,要坚持:

    ...
    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())));
于 2015-09-26T12:24:29.743 回答
1
于 2015-09-27T07:30:41.840 回答
0

尝试使用LocalDate#toDateMidnight()将时间设置为 0 然后DateMidnight#toDate().

Date date = localDate.toDateMidnight().toDate();

或者,如果您使用的是 JodaTime 1.5 或更新版本,请使用LocalDate#toDateTimeAtStartOfDay()然后DateTime#toDate()

希望有所帮助

于 2013-04-24T11:15:51.940 回答