java.util.Date到java.sql.Date不包含Time

我在PreparedStatement上遇到SqlException ,因为它违反了表(dupe key)上的唯一性约束。 基本上我的表看起来像这样:

 mytable ======= mytable_id PRIMARY KEY INT NOT NULL fizz_id INT NOT NULL buzz_timestamp DATETIME 

唯一性约束在buzz_timestamp ; 也就是说,没有2条记录可能具有相同的日期/时间“timestamp”。

将记录插入此表的PreparedStatement如下所示:

 PreparedStatement ps = conn.prepareStatement(insertQuery); ps.setDate(1, new java.sql.Date(new java.util.Date().getTime())); 

所以你可以看到我正在使用java.util.Date() (“now”)并将其转换为java.sql.Date实例。

我看到的确切错误(欺骗密钥)一直在抱怨我正在尝试将2015-05-27 00:00:00.0000000插入到buzz_timestamp的表中,但它已经存在。 所以,显然,我使用的是Date API错误,并且我正在插入具有已淘汰时间组件的日期,从而产生欺骗性密钥exception。

所以我问: 我如何纠正这一点,以便我真正插入“现在”的日期和时间?

使用

 ps.setTimestamp(new java.sql.Timestamp(System.currentTimeMillis()); 

请参阅: 在PreparedStatement中使用setDate

java.sql.Date扩展了java.util.Date但工作方式不同:在SQL中, DATE没有时间。 因此,Java对象也会忽略小时,分钟等。

请尝试使用java.sql.Timestamp但您可能需要使用DATETIME转换(在SQL中)将其转换为DATETIME

有关:

  • mssql 2005 datetime和jdbc

接受的答案是正确的。 我会补充说明。

困惑哈克

在SQL中,DATE是仅限日期的值,缺少时间或时区。

与Java捆绑在一起的旧日期时间类的混乱缺少任何此类来表示仅限日期的值。

相反,Java团队创建了一个hack。 他们通过扩展java.util.Date创建了java.sql.Date,尽管它的名称令人困惑,但它有一个日期部分一个时间部分。 对于面向SQL的子类,它们将时间部分设置为零值。 你可能会认为那是“午夜”。 所以java.sql.Date 一个时间,但假装没有。

引用java.SQL.Date doc:

为了符合SQL DATE的定义,java.sql.Date实例包含的毫秒值必须通过在与实例关联的特定时区中将小时,分钟,秒和毫秒设置为零来“标准化”。 。

对于SQL中的日期和时间值,请使用java.sql.Timestamp类,如接受的答案中所示。

java.time

这些设计糟糕的日期时间类已被Java 8及更高版本中内置的新java.time包取代。 这个软件包的灵感来自Joda-Time库。

Java.time包中包含表示仅限日期和仅限时间类的类。 最终,JDBC驱动程序将升级为直接支持新数据类型。 在此之前,请使用添加到旧类和新类的几种转换方法。 搜索StackOverflow.com的许多示例和讨论,因为这个问题在很大程度上是重复的。

您需要尝试setTimestamp而不是setDate

 java.sql.Date - A date only (no time part) java.sql.Time - A time only (no date part) java.sql.Timestamp - Both date and time